react-fs-router 0.2.17 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/README.md +36 -28
  2. package/genPath.js +91 -44
  3. package/index.js +18 -7
  4. package/package.json +7 -5
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # React-fs-router
2
2
 
3
- React-fs-router is a simple library that watches a user-provided route for changes in files and generates two files in a user-provided route to be used with react-router.
3
+ A cli library that watches a user-provided path for changes in files and folders and genarates two files to implement file-system based routing.
4
4
 
5
5
  ## Installation
6
6
 
@@ -16,42 +16,46 @@ npm install react-fs-router
16
16
 
17
17
  ## Usage
18
18
 
19
- The name of each file will be used as its path. The path for index files is "/". Each folder is treated as a route and each file inside a folder is treated as a subroute of its parent folder.
19
+ The position of a file in the folder structure defines it's path. Files named index are treated as the root and default file in each folder.
20
+ You can define a dynamic route by placing the name of the file in brackets. ie: [id].js ==> :id
20
21
 
21
- As of yet, react-fs-router runs via a command that must be added to the script section of your package.json file.
22
- The path to pages folder and the path for the output files must be passes via command:
22
+ | Arguments | Result |
23
+ | ------------------------------- | ------------------------------------------------------------------------------------------------------------- |
24
+ | -i \| --input <directory> | Path to watch for changes. Required. |
25
+ | -o \| --output <output> | Optional argument that takes a path to place output files in. Defaults to the input directory. |
26
+ | -ext \| --extention <extention> | Optional argument to change the file extension of the output files. Defaults to .js . |
27
+ | -p \| --pageProperties [type] | Optional boolean argument to disable generating page_properties file. Defaults to false. |
28
+ | -b \| --build [type] | Optional boolean argument that tells the program to run once. Defaults to false. Intended for build commands. |
23
29
 
24
30
  ```JSON
25
31
  "scripts": {
26
- "rfr": "rfr -p <path to pages folder> -c <path to place output files>"
32
+ "rfr": "rfr -d <path to pages folder>"
27
33
  }
28
34
  ```
29
35
 
30
- -b can be passed to tell the program to run only once. Intended to be used with the build script.
31
-
32
36
  Run the development server
33
37
 
34
38
  ```bash
35
39
  npm run start
36
40
  ```
37
41
 
38
- Then run react-fs-router
42
+ Run react-fs-router
39
43
 
40
44
  ```bash
41
45
  npm run rfr
42
46
  ```
43
47
 
44
- The program will then generate two files one containing imports and exports of all the files inside the pages path and one containing an array of objects each containing:
48
+ The program will then generate two files one containing imports and exports of all the files inside the provided path and one containing an array of objects per each file. The properties in the mentioned object are as follows:
45
49
 
46
50
  ```javascript
47
- {
48
- component://Name of the default export of the file
49
- name: //Name of the component mentioned in the file
50
- icon: //Name of the icon mentioned in the file
51
- index: //A number by which the objects in this array are sorted by
51
+
52
+ component: // Name of the default export of the file
53
+ name: // Name of the component mentioned in the file as // name: string
54
+ icon: // Name of the icon mentioned in the file as // icon: string
55
+ index: // A number by which the objects in this array are sorted by. mentioned in the file as // index: number
52
56
  file: // The name of the file this object is for
53
- path: // The path of this file in relation to its position in the folder structure.
54
- }
57
+ path: // The path of this file in relation to its position in the folder structure. index files are always "/"
58
+
55
59
  ```
56
60
 
57
61
  Name, icon and index can be written in each file and react-fs-router will read and place them in the output file.
@@ -62,7 +66,7 @@ Name, icon and index can be written in each file and react-fs-router will read a
62
66
  // index: 0
63
67
  ```
64
68
 
65
- To use with the react-router:
69
+ To use the generated files with react-router:
66
70
 
67
71
  ```javascript xml react
68
72
  // importing all of the files from the imports-exports file
@@ -76,7 +80,6 @@ function App() {
76
80
  const [pages, setPages] = useState();
77
81
 
78
82
  useEffect(() => {
79
- // calling the function to genarate routes.
80
83
  setPages(renderConponents(Pages));
81
84
  }, []);
82
85
 
@@ -106,7 +109,7 @@ function App() {
106
109
  }
107
110
  ```
108
111
 
109
- Place this component inside <BrowserRouter>
112
+ Place this component inside BrowserRouter
110
113
 
111
114
  ```xml
112
115
  <BrowserRouter>
@@ -114,10 +117,10 @@ Place this component inside <BrowserRouter>
114
117
  </BrowserRouter>
115
118
  ```
116
119
 
117
- ## Using with AntPro Layout
120
+ ## Using with Ant Pro Layout
118
121
 
119
122
  The routes array generated by this library can be easily used with Ant designs pro layout component.
120
- The following is an an example using an hoc:
123
+ The following is an example using an hoc:
121
124
 
122
125
  ```javascript xml
123
126
  import { routes } from "../../config/routeConfigs";
@@ -168,17 +171,22 @@ function Layout(Component) {
168
171
  }
169
172
  ```
170
173
 
171
- ## Caveats
174
+ ## Usage with Concurrently
172
175
 
173
- 1. Since all of the files are wrriten into imports and exports file, having two files with the same name as default export will cause an error.
174
- 2. Running this package with the start command is not recommended as it interferes with react script unless -b is passed to run the main function of the package once.
175
- 3. This library is a work in progress. Feel free to discuss your issues in the github page of the library.
176
+ You can use [concurrently](https://www.npmjs.com/package/concurrently) to run rfr with react at the same time.
176
177
 
177
- ## Contributing
178
+ ```bash
179
+ npm install -g concurrently
180
+ ```
178
181
 
179
- Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
182
+ ```bash
183
+ concurrently --kill-others "npm run start" "npm run rfr"
184
+ ```
185
+
186
+ ## Caveats
180
187
 
181
- Please make sure to update tests as appropriate.
188
+ 1. Since all of the files are imported and re-exported, having two files with the same name as default export will cause an error.
189
+ 2. Running this package along with the react start script is not recommended as it interferes with the react script. Consider using a package like concurrently for this purpose.
182
190
 
183
191
  ## License
184
192
 
package/genPath.js CHANGED
@@ -4,12 +4,47 @@ const chokidar = require("chokidar");
4
4
 
5
5
  let isNotThefirstTimeRunning = true;
6
6
 
7
- const genPath = (page_directory, configs_directory, runOnce) => {
7
+ const genPath = (
8
+ page_directory,
9
+ configs_directory,
10
+ runOnce,
11
+ file_extention,
12
+ dont_output_fileProperties
13
+ ) => {
14
+ //main function
8
15
  const pathMaker = () => {
16
+ //parse parameters in path
17
+ const parsePageName = (fileName) => {
18
+ const isParam = fileName.includes("[") && fileName.includes("]");
19
+
20
+ const splitFileName = fileName.split("/");
21
+ if (splitFileName.length && isParam) {
22
+ const paramName = splitFileName[splitFileName.length - 1];
23
+ const paramNameWithoutExtention = paramName.split(".")[0];
24
+ const paramNameWithoutBraces = paramNameWithoutExtention
25
+ .replace("[", "")
26
+ .replace("]", "");
27
+ splitFileName[splitFileName.length - 1] = `:${paramNameWithoutBraces}`;
28
+ return splitFileName.join("/");
29
+ } else if (fileName === "index" && !isParam) return "";
30
+ else return fileName;
31
+ };
32
+
33
+ const parseFilePath = (filePath) => {
34
+ if (filePath.includes(":")) {
35
+ const splitPath = filePath.split("/");
36
+ const lastItemInPath = splitPath[splitPath.length - 1].replace(":", "");
37
+ splitPath[splitPath.length - 1] = `[${lastItemInPath}]`;
38
+ return splitPath.join("/");
39
+ } else return filePath;
40
+ };
41
+
42
+ //read page directory
9
43
  const readDirectory = (directory, includeDirectory) => {
10
44
  const pages = {};
11
45
  const read = fs.readdirSync(directory);
12
- read.forEach((page) => {
46
+ const readFiltered = read.filter((file) => !file.startsWith("_"));
47
+ readFiltered.forEach((page) => {
13
48
  const name = page.split(".")[0];
14
49
  if (page.includes(".")) {
15
50
  pages[page.replace(".", "_")] = `${
@@ -21,6 +56,7 @@ const genPath = (page_directory, configs_directory, runOnce) => {
21
56
  });
22
57
  return pages;
23
58
  };
59
+
24
60
  const pages = readDirectory(page_directory);
25
61
 
26
62
  const readFileProperties = (filepath) => {
@@ -77,8 +113,9 @@ const genPath = (page_directory, configs_directory, runOnce) => {
77
113
  if (name) route.name = name;
78
114
  if (icon) route.icon = icon;
79
115
  if (index) route.index = index;
80
- if (filepath) route.path = filepath;
116
+ if (filepath) route.path = parsePageName(filepath);
81
117
  if (filename) route.file = filename.replace("_", ".");
118
+
82
119
  return route;
83
120
  };
84
121
 
@@ -106,23 +143,33 @@ const genPath = (page_directory, configs_directory, runOnce) => {
106
143
  node?.component
107
144
  ? `import ${node.component} from "${
108
145
  process.env.PWD + page_directory.replace(".", "")
109
- }${node.path === "/" ? "" : node.path}";`
146
+ }${node.path === "/" ? "" : parseFilePath(node.path)}";`
110
147
  : ""
111
148
  )
112
149
  .join("")} \n \n export{${routes
113
150
  .map((node) => (node?.component ? `${node.component},` : ""))
114
151
  .join("")}};`;
115
152
 
116
- fs.writeFileSync(
117
- configs_directory + "/routeConfigs.js",
118
- prettier.format(_config, { semi: false, parser: "babel" }),
119
- (err) => {
120
- if (err) return console.error(err);
121
- }
122
- );
153
+ const parseFileExtention = (ext) => {
154
+ if (ext) {
155
+ if (ext.includes(".")) return ext;
156
+ else return "." + ext;
157
+ } else return ".js";
158
+ };
159
+ if (!dont_output_fileProperties) {
160
+ fs.writeFileSync(
161
+ (configs_directory || page_directory) +
162
+ `/_page-properties${parseFileExtention(file_extention)}`,
163
+ prettier.format(_config, { semi: false, parser: "babel" }),
164
+ (err) => {
165
+ if (err) return console.error(err);
166
+ }
167
+ );
168
+ }
123
169
 
124
170
  fs.writeFileSync(
125
- configs_directory + "/route.js",
171
+ (configs_directory || page_directory) +
172
+ `/_routes${parseFileExtention(file_extention)}`,
126
173
  prettier.format(_routes, { semi: false, parser: "babel" }),
127
174
  (err) => {
128
175
  if (err) return console.error(err);
@@ -134,40 +181,40 @@ const genPath = (page_directory, configs_directory, runOnce) => {
134
181
  pathMaker();
135
182
  isNotThefirstTimeRunning = false;
136
183
  }
184
+
137
185
  const watcher = chokidar.watch(page_directory, {
138
- ignored: /^\./,
139
- persistent: true,
186
+ ignored: /^\.|\_/,
187
+ persistent: !runOnce,
140
188
  });
141
- if (!runOnce) {
142
- watcher
143
- .on("add", function (path) {
144
- try {
145
- pathMaker();
146
- } catch (e) {
147
- console.log(e);
148
- }
149
- console.log("File", path, "has been added");
150
- })
151
- .on("change", function (path) {
152
- try {
153
- pathMaker();
154
- } catch (e) {
155
- console.log(e);
156
- }
157
- console.log("File", path, "has been changed");
158
- })
159
- .on("unlink", function (path) {
160
- try {
161
- pathMaker();
162
- } catch (e) {
163
- console.log(e);
164
- }
165
- console.log("File", path, "has been removed");
166
- })
167
- .on("error", function (error) {
168
- console.error("Error happened", error);
169
- });
170
- }
189
+
190
+ watcher
191
+ .on("add", function (path) {
192
+ try {
193
+ pathMaker();
194
+ } catch (e) {
195
+ console.log(e);
196
+ }
197
+ console.log("File", path, "has been added");
198
+ })
199
+ .on("change", function (path) {
200
+ try {
201
+ pathMaker();
202
+ } catch (e) {
203
+ console.log(e);
204
+ }
205
+ console.log("File", path, "has been changed");
206
+ })
207
+ .on("unlink", function (path) {
208
+ try {
209
+ pathMaker();
210
+ } catch (e) {
211
+ console.log(e);
212
+ }
213
+ console.log("File", path, "has been removed");
214
+ })
215
+ .on("error", function (error) {
216
+ console.error("Error happened", error);
217
+ });
171
218
  };
172
219
 
173
220
  module.exports = { genPath };
package/index.js CHANGED
@@ -5,21 +5,32 @@ const { Command } = require("commander");
5
5
  const { version, name } = require("./package.json");
6
6
 
7
7
  const program = new Command();
8
+
8
9
  program.storeOptionsAsProperties(name);
9
10
 
10
11
  program.version(version, "-v --version", "Output the current version");
11
-
12
- program.requiredOption("-p,--page <page>", "Path to your pages folder");
13
- program.requiredOption(
14
- "-c,--configs <configs>",
15
- "Path to store generated files"
12
+ program.requiredOption("-i,--input <directory>", "Path to your pages folder");
13
+ program.option("-o,--output <output>", "Path to store generated files");
14
+ program.option(
15
+ "-ext,--extention <extention>",
16
+ "extention on the generated files"
16
17
  );
17
18
 
19
+ program.option(
20
+ "-p,--pageProperties [type]",
21
+ "Boolean option to disable genrating page properties file"
22
+ );
18
23
  program.option(
19
24
  "-b,--build [type]",
20
- "boolean Option to run the program once. Intended to be with build commands."
25
+ "Boolean Option to run the program once. Intended to be used with build commands."
21
26
  );
22
27
 
23
28
  program.parse();
24
29
 
25
- genPath(program.page, program.configs);
30
+ genPath(
31
+ program.input,
32
+ program.output,
33
+ program.build,
34
+ program.extention,
35
+ program.pageProperties
36
+ );
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "react-fs-router",
3
- "version": "0.2.17",
3
+ "version": "1.0.0",
4
4
  "description": "File-system based routing for React.",
5
5
  "main": "./index.js",
6
6
  "git repository": "https://github.com/Mehran9675/react-filesystem-routing",
7
7
  "scripts": {
8
- "test": "node ./index.js -p ./pages -c ./configs",
8
+ "test": "node ./index.js -i ./pages -ext ts",
9
9
  "build": "npx -p typescript tsc"
10
10
  },
11
11
  "keywords": [
@@ -18,9 +18,7 @@
18
18
  "license": "MIT",
19
19
  "dependencies": {
20
20
  "chokidar": "^3.5.2",
21
- "commander": "^8.2.0",
22
- "react": "^17.0.2",
23
- "react-router-dom": "^5.3.0"
21
+ "commander": "^8.2.0"
24
22
  },
25
23
  "bin": {
26
24
  "react-fs-router": "./index.js",
@@ -30,4 +28,8 @@
30
28
  "typescript": "^4.4.4",
31
29
  "prettier": "^2.4.1"
32
30
  }
31
+ ,"repository": {
32
+ "type":"git",
33
+ "url":"https://github.com/Mehran9675/react-filesystem-routing"
34
+ }
33
35
  }