├── babel.config.json
├── .prettierrc
├── .npmignore
├── .gitignore
├── src
├── utils
│ ├── getScreenSize.js
│ └── debounce.js
└── index.js
├── .eslintrc
├── package.json
└── README.md
/babel.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@babel/preset-react", "@babel/preset-env", "minify"]
3 | }
4 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "endOfLine": "lf",
3 | "semi": true,
4 | "singleQuote": true,
5 | "tabWidth": 2,
6 | "trailingComma": "es5"
7 | }
8 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .idea
2 | .vscode
3 | build
4 | node_modules
5 | src
6 | .eslintrc
7 | .prettierrc
8 | .npmignore
9 | babel.config.json
10 | yarn.lock
11 | package-lock.json
12 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | .vscode
3 | lib
4 | node_modules
5 | .DS_Store
6 | yarn.lock
7 | package-lock.json
8 | index.js
9 |
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
--------------------------------------------------------------------------------
/src/utils/getScreenSize.js:
--------------------------------------------------------------------------------
1 | const getScreenSize = () => {
2 | return {
3 | width: window.innerWidth,
4 | height: window.innerHeight,
5 | };
6 | };
7 |
8 | export default getScreenSize;
9 |
--------------------------------------------------------------------------------
/src/utils/debounce.js:
--------------------------------------------------------------------------------
1 | const debounce = (func, delay) => {
2 | let timeoutId;
3 |
4 | return function (...args) {
5 | if (timeoutId) {
6 | clearTimeout(timeoutId);
7 | }
8 |
9 | timeoutId = setTimeout(() => {
10 | func(...args);
11 | }, delay);
12 | };
13 | };
14 |
15 | export default debounce;
16 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "es6": true
5 | },
6 | "parser": "babel-eslint",
7 | "rules": {
8 | "strict": 1,
9 | "no-console": 1
10 | },
11 | "extends": [
12 | "eslint:recommended",
13 | "plugin:react/recommended",
14 | "plugin:prettier/recommended"
15 | ],
16 | "settings": {
17 | "react": {
18 | "version": "detect"
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from 'react';
2 |
3 | import getScreenSize from './utils/getScreenSize';
4 | import debounce from './utils/debounce';
5 |
6 | const currentScreenSize = (settings = { debounceTime: 200 }) => {
7 | const [screenSize, setScreenSize] = useState(getScreenSize());
8 | const handleResize = () => setScreenSize(getScreenSize());
9 | const handleResizeDebounced = debounce(handleResize, settings.debounceTime);
10 |
11 | useEffect(() => {
12 | window.addEventListener('resize', handleResizeDebounced);
13 |
14 | return () => {
15 | window.removeEventListener('resize', handleResizeDebounced);
16 | };
17 | }, []);
18 |
19 | return {
20 | width: screenSize.width,
21 | height: screenSize.height,
22 | };
23 | };
24 |
25 | export default currentScreenSize;
26 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "my-new-module",
3 | "version": "1.0.0",
4 | "description": "NPM module template description",
5 | "keywords": [
6 | "react",
7 | "hooks",
8 | "screen size"
9 | ],
10 | "private": false,
11 | "main": "lib/index.js",
12 | "scripts": {
13 | "build": "babel src --out-dir lib",
14 | "develop": "babel -w src --out-dir lib",
15 | "deploy": "npm publish"
16 | },
17 | "author": "",
18 | "license": "ISC",
19 | "peerDependencies": {
20 | "react": "^16.6.1",
21 | "react-dom": "^16.13.1"
22 | },
23 | "devDependencies": {
24 | "@babel/cli": "^7.10.5",
25 | "@babel/core": "^7.10.5",
26 | "@babel/preset-env": "^7.10.4",
27 | "@babel/preset-react": "^7.10.4",
28 | "babel-eslint": "^10.1.0",
29 | "babel-preset-minify": "^0.5.1",
30 | "eslint": "^7.5.0",
31 | "eslint-config-prettier": "^6.11.0",
32 | "eslint-plugin-prettier": "^3.1.4",
33 | "eslint-plugin-react": "^7.20.3",
34 | "prettier": "^2.0.5"
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # NPM module template
2 | Typescript implementation is available in a following [repo](https://github.com/Halo-Lab/react-hook-module-template-typescript)
3 |
4 |
5 | Boilerplate to create an npm module development environment with example code (custom hook that track window dimensions).
6 |
7 | > Our setup will consist of two separate projects:
8 | > 1. NPM Module Project
9 | > 2. React Host Project (to debug new features)
10 |
11 | 
12 |
13 | NPM module will be connected to the React Host Project using `npm link`. Project separation will enable us to keep our module logic encapsulated and more maintainable.
14 |
15 |
16 | ## Available script commands
17 |
18 | Build `src` to `lib` folder.
19 | ```
20 | npm run build
21 | ```
22 | Run development will compile a file every time that any changes in `/src` folder will occur.
23 | ```
24 | npm run develop
25 | ```
26 | Deploy your project to NPM. The script will trigger `npm publish`.
27 | ```
28 | npm run deploy
29 | ```
30 |
31 |
32 |
33 | ## 🚀 Quick start
34 |
35 | 1. Clone template project.
36 | ```
37 | git clone https://github.com/Halo-Lab/react-hook-module-template
38 | ```
39 | 2. Pick a module name and change folder name in `package.json` accordingly. Make sure you are using a unique one so you can publish your package to npm. Provide additional information about your module by changing *description*, *author*, *license* and *keywords*. Describe basic functionality of your module in `README.md` file.
40 |
41 | *project folder*
42 | ```
43 | /my-new-module
44 | ```
45 |
46 | *package.json*
47 | ```json
48 | "name": "my-new-module",
49 | "description": "NPM module template description",
50 | "author": "John Smith",
51 | "license": "ISC",
52 | "keywords": ["react", "hooks", "screen size"]
53 | ```
54 |
55 | 3. Install dependencies
56 |
57 | ```
58 | npm i
59 | ```
60 |
61 | 4. An initial build command will compile all files from `/src` folder to a single `/lib` folder.
62 | ```
63 | npm run build
64 | ```
65 | 5. Our module is ready for development. Now we are ready to connect our module to React Host Project. Create a new React Project in the different folder and change `App.js` file with example code. **Main concept is to keep two projects in separate folders. So after the development process Module Project will include
66 | module logic exclusively.**
67 |
68 | > Be sure that you're **not** creating new project inside Module folder.
69 |
70 | *Navigate to your main Project Folder and create a new React Project.*
71 | ```
72 | cd ..
73 | npx create-react-app host_react_app
74 | ```
75 | *App.js*
76 | ```jsx
77 | import React from 'react';
78 | import useResizing from 'my-new-module';
79 |
80 | function App() {
81 | const screenSize = useResizing();
82 |
83 | return (
84 |
132 |
133 |
--------------------------------------------------------------------------------