react-fs-router 0.2.20 → 1.0.11

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.
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/react-filesystem-router.iml" filepath="$PROJECT_DIR$/.idea/react-filesystem-router.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="WEB_MODULE" version="4">
3
+ <component name="NewModuleRootManager">
4
+ <content url="file://$MODULE_DIR$">
5
+ <excludeFolder url="file://$MODULE_DIR$/temp" />
6
+ <excludeFolder url="file://$MODULE_DIR$/.tmp" />
7
+ <excludeFolder url="file://$MODULE_DIR$/tmp" />
8
+ </content>
9
+ <orderEntry type="inheritedJdk" />
10
+ <orderEntry type="sourceFolder" forTests="false" />
11
+ </component>
12
+ </module>
package/.idea/vcs.xml ADDED
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="$PROJECT_DIR$" vcs="Git" />
5
+ </component>
6
+ </project>
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 folders 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,45 +16,49 @@ 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 arguments as -p for input folder to watch and -c for the output files:
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 re-exports of all the files inside the provided input path and one containing an array of objects per each file. The properties in the mentioned object are as follows:
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
51
 
48
- component:// Name of the default export of the file
52
+ component: // Name of the default export of the file
49
53
  name: // Name of the component mentioned in the file as // name: string
50
54
  icon: // Name of the icon mentioned in the file as // icon: string
51
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
57
  path: // The path of this file in relation to its position in the folder structure. index files are always "/"
54
- }=
58
+
55
59
  ```
56
60
 
57
- Name, icon and index can be written in each file and react-fs-router will read and place them in the output file.
61
+ Name, icon and index can be written in each file as comments and react-fs-router will read and place them in the output file.
58
62
 
59
63
  ```javascript
60
64
  // name: Home
@@ -65,13 +69,6 @@ Name, icon and index can be written in each file and react-fs-router will read a
65
69
  To use the generated files with react-router:
66
70
 
67
71
  ```javascript xml react
68
- // importing all of the files from the imports-exports file
69
- import * as Pages from "src/config/route";
70
- // importing the route objects
71
- import { routes } from "src/config/routeConfigs";
72
-
73
- import { Route, Switch } from "react-router-dom";
74
-
75
72
  function App() {
76
73
  const [pages, setPages] = useState();
77
74
 
@@ -119,11 +116,6 @@ The routes array generated by this library can be easily used with Ant designs p
119
116
  The following is an example using an hoc:
120
117
 
121
118
  ```javascript xml
122
- import { routes } from "../../config/routeConfigs";
123
- import * as Icons from "@ant-design/icons";
124
- import { Row } from "antd";
125
- import ProLayout, { PageContainer } from "@ant-design/pro-layout";
126
- import { Link } from "react-router-dom";
127
119
  function Layout(Component) {
128
120
  return class extends React.Component {
129
121
  state = {
@@ -167,11 +159,22 @@ function Layout(Component) {
167
159
  }
168
160
  ```
169
161
 
162
+ ## Usage with Concurrently
163
+
164
+ You can use [concurrently](https://www.npmjs.com/package/concurrently) to run rfr with react at the same time.
165
+
166
+ ```bash
167
+ npm install -g concurrently
168
+ ```
169
+
170
+ ```bash
171
+ concurrently --kill-others "npm run start" "npm run rfr"
172
+ ```
173
+
170
174
  ## Caveats
171
175
 
172
176
  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.
173
- 2. Running this package with the start command is not recommended as it interferes with the react script.
174
- 3. This library is a work in progress and is consistantly being improved. Feel free to open issues in the github repo.
177
+ 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.
175
178
 
176
179
  ## License
177
180
 
package/genPath.js CHANGED
@@ -5,11 +5,40 @@ const chokidar = require("chokidar");
5
5
  let isNotThefirstTimeRunning = true;
6
6
 
7
7
  const genPath = (page_directory, configs_directory, runOnce) => {
8
+ //main function
8
9
  const pathMaker = () => {
10
+ //parse parameters in path
11
+ const parsePageName = (fileName) => {
12
+ const isParam = fileName.includes("[") && fileName.includes("]");
13
+
14
+ const splitFileName = fileName.split("/");
15
+ if (splitFileName.length && isParam) {
16
+ const paramName = splitFileName[splitFileName.length - 1];
17
+ const paramNameWithoutExtention = paramName.split(".")[0];
18
+ const paramNameWithoutBraces = paramNameWithoutExtention
19
+ .replace("[", "")
20
+ .replace("]", "");
21
+ splitFileName[splitFileName.length - 1] = `:${paramNameWithoutBraces}`;
22
+ return splitFileName.join("/");
23
+ } else if (fileName === "index" && !isParam) return "";
24
+ else return fileName;
25
+ };
26
+
27
+ const parseFilePath = (filePath) => {
28
+ if (filePath.includes(":")) {
29
+ const splitPath = filePath.split("/");
30
+ const lastItemInPath = splitPath[splitPath.length - 1].replace(":", "");
31
+ splitPath[splitPath.length - 1] = `[${lastItemInPath}]`;
32
+ return splitPath.join("/");
33
+ } else return filePath;
34
+ };
35
+
36
+ //read page directory
9
37
  const readDirectory = (directory, includeDirectory) => {
10
38
  const pages = {};
11
39
  const read = fs.readdirSync(directory);
12
- read.forEach((page) => {
40
+ const readFiltered = read.filter((file) => !file.startsWith("_"));
41
+ readFiltered.forEach((page) => {
13
42
  const name = page.split(".")[0];
14
43
  if (page.includes(".")) {
15
44
  pages[page.replace(".", "_")] = `${
@@ -21,6 +50,7 @@ const genPath = (page_directory, configs_directory, runOnce) => {
21
50
  });
22
51
  return pages;
23
52
  };
53
+
24
54
  const pages = readDirectory(page_directory);
25
55
 
26
56
  const readFileProperties = (filepath) => {
@@ -77,8 +107,9 @@ const genPath = (page_directory, configs_directory, runOnce) => {
77
107
  if (name) route.name = name;
78
108
  if (icon) route.icon = icon;
79
109
  if (index) route.index = index;
80
- if (filepath) route.path = filepath;
110
+ if (filepath) route.path = parsePageName(filepath);
81
111
  if (filename) route.file = filename.replace("_", ".");
112
+
82
113
  return route;
83
114
  };
84
115
 
@@ -106,15 +137,22 @@ const genPath = (page_directory, configs_directory, runOnce) => {
106
137
  node?.component
107
138
  ? `import ${node.component} from "${
108
139
  process.env.PWD + page_directory.replace(".", "")
109
- }${node.path === "/" ? "" : node.path}";`
140
+ }${node.path === "/" ? "" : parseFilePath(node.path)}";`
110
141
  : ""
111
142
  )
112
143
  .join("")} \n \n export{${routes
113
144
  .map((node) => (node?.component ? `${node.component},` : ""))
114
145
  .join("")}};`;
115
146
 
147
+ const parseFileExtention = (ext) => {
148
+ if (ext) {
149
+ if (ext.includes(".")) return ext;
150
+ else return "." + ext;
151
+ } else return ".js";
152
+ };
116
153
  fs.writeFileSync(
117
- configs_directory + "/routeConfigs.js",
154
+ (configs_directory || page_directory) +
155
+ `/_page-properties${parseFileExtention(".js")}`,
118
156
  prettier.format(_config, { semi: false, parser: "babel" }),
119
157
  (err) => {
120
158
  if (err) return console.error(err);
@@ -122,7 +160,8 @@ const genPath = (page_directory, configs_directory, runOnce) => {
122
160
  );
123
161
 
124
162
  fs.writeFileSync(
125
- configs_directory + "/route.js",
163
+ (configs_directory || page_directory) +
164
+ `/_routes${parseFileExtention(".js")}`,
126
165
  prettier.format(_routes, { semi: false, parser: "babel" }),
127
166
  (err) => {
128
167
  if (err) return console.error(err);
@@ -134,40 +173,40 @@ const genPath = (page_directory, configs_directory, runOnce) => {
134
173
  pathMaker();
135
174
  isNotThefirstTimeRunning = false;
136
175
  }
176
+
137
177
  const watcher = chokidar.watch(page_directory, {
138
- ignored: /^\./,
139
- persistent: true,
178
+ ignored: /^\.|\_/,
179
+ persistent: !runOnce,
140
180
  });
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
- }
181
+
182
+ watcher
183
+ .on("add", function (path) {
184
+ try {
185
+ pathMaker();
186
+ } catch (e) {
187
+ console.log(e);
188
+ }
189
+ console.log("File", path, "has been added");
190
+ })
191
+ .on("change", function (path) {
192
+ try {
193
+ pathMaker();
194
+ } catch (e) {
195
+ console.log(e);
196
+ }
197
+ console.log("File", path, "has been changed");
198
+ })
199
+ .on("unlink", function (path) {
200
+ try {
201
+ pathMaker();
202
+ } catch (e) {
203
+ console.log(e);
204
+ }
205
+ console.log("File", path, "has been removed");
206
+ })
207
+ .on("error", function (error) {
208
+ console.error("Error happened", error);
209
+ });
171
210
  };
172
211
 
173
212
  module.exports = { genPath };
package/index.js CHANGED
@@ -5,21 +5,15 @@ 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"
16
- );
17
-
12
+ program.requiredOption("-i,--input <directory>", "Path to your pages folder");
18
13
  program.option(
19
14
  "-b,--build [type]",
20
- "boolean Option to run the program once. Intended to be with build commands."
15
+ "Boolean Option to run the program once. Intended to be used with build commands."
21
16
  );
22
-
23
17
  program.parse();
24
18
 
25
- genPath(program.page, program.configs, program.build);
19
+ genPath(program.input, program.build);
File without changes
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "react-fs-router",
3
- "version": "0.2.20",
3
+ "version": "1.0.11",
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": [