rebuiltron 5.0.0 → 6.0.1
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.
- package/README.md +29 -12
- package/configurations/base.js +3 -52
- package/configurations/main.js +13 -1
- package/configurations/preloads.js +11 -2
- package/configurations/renderers.js +60 -2
- package/helpers/paths.js +0 -6
- package/loaders/javascript.js +0 -11
- package/loaders/style.js +1 -1
- package/package.json +20 -19
- package/rebuiltronConfig.js +1 -1
- package/scripts/build.js +5 -18
- package/scripts/start.js +12 -8
- package/tasks/buildApp.js +65 -0
- package/{checkSetup.js → tasks/checkSetup.js} +8 -4
- package/tasks/compileMain.js +41 -0
- package/tasks/startDevServer.js +45 -0
- package/tasks/startElectron.js +40 -0
- package/tasks/watchPreloads.js +73 -0
- package/webpack.config.js +8 -2
- package/buildApp.js +0 -33
- package/createDevServer.js +0 -73
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ A tool made to easily build an offline **React/Electron** app using webpack.
|
|
|
9
9
|
The idea behind Rebuiltron was to migrate one of my project initially created with the deprecated [CRA](https://create-react-app.dev/) to a maintained tool configured with Electron in mind. As such, it has been developed using [react-scripts](https://github.com/facebook/create-react-app/tree/main/packages/react-scripts) as a base, but heavily edited and stripped of a lot of features.
|
|
10
10
|
|
|
11
11
|
> [!IMPORTANT]
|
|
12
|
-
> Since I made Rebuiltron specifically for one of my own projects, I only kept in the configuration what *this* project needed and nothing more. Except for the entry points and some
|
|
12
|
+
> Since I made Rebuiltron specifically for one of my own projects, I only kept in the configuration what *this* project needed and nothing more. Except for the entry points and some basic options, **Rebuiltron doesn't offer many configurable options**. If you are looking to create a new Electron/React app, or even migrating an existing CRA app, you should probably look for a more generic tool.
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
## Features
|
|
@@ -20,10 +20,10 @@ Rebuiltron uses webpack with [SWC](https://swc.rs/) to compile JavaScript instea
|
|
|
20
20
|
- Development server taking care of starting Electron
|
|
21
21
|
- Production bundler for React and Electron code
|
|
22
22
|
- Support for React, JSX, SASS, ICSS
|
|
23
|
-
- Support for
|
|
23
|
+
- Support for ES6 imports on all processes
|
|
24
24
|
|
|
25
25
|
> [!WARNING]
|
|
26
|
-
> Rebuiltron **doesn't support**: TypeScript, Flow, CSS Modules, Jest, and proxying.
|
|
26
|
+
> Rebuiltron **doesn't support**: TypeScript, Flow, CSS Modules, ESM, Jest, and proxying.
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
## Installation
|
|
@@ -36,7 +36,7 @@ yarn add rebuiltron -D
|
|
|
36
36
|
|
|
37
37
|
## Configuration
|
|
38
38
|
|
|
39
|
-
The following documentation
|
|
39
|
+
The following documentation assumes you already have a basic knowledge of how to use React and Electron.
|
|
40
40
|
|
|
41
41
|
### Folder structure
|
|
42
42
|
|
|
@@ -56,12 +56,14 @@ Set the main Electron entry in `package.json`:
|
|
|
56
56
|
|
|
57
57
|
```json
|
|
58
58
|
{
|
|
59
|
-
"main": "electron
|
|
59
|
+
"main": "build/static/js/electron.main.js",
|
|
60
60
|
}
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
+
This field points to the compiled version of the main file and **must** be named as above. Your original main file can be named however you want.
|
|
64
|
+
|
|
63
65
|
### Scripts
|
|
64
|
-
Add Rebuiltron scripts
|
|
66
|
+
Add Rebuiltron scripts to your `package.json`:
|
|
65
67
|
|
|
66
68
|
```json
|
|
67
69
|
{
|
|
@@ -84,12 +86,13 @@ Add your desired [browserslist](https://github.com/browserslist/browserslist) in
|
|
|
84
86
|
|
|
85
87
|
### Configuration file
|
|
86
88
|
|
|
87
|
-
At the root of your project, create a `rebuiltron.config.
|
|
89
|
+
At the root of your project, create a `rebuiltron.config.js` file.
|
|
88
90
|
|
|
89
91
|
#### Options:
|
|
90
92
|
|
|
91
|
-
|
|
|
93
|
+
| Name | Type | Required | Description |
|
|
92
94
|
| --- | :---: | :---: | --- |
|
|
95
|
+
| `main` | `string` | ✓ | Main entry. The path must be relative.
|
|
93
96
|
| `renderers` | `object` | ✓ | Renderer entries. It takes the name of the entries as keys and their paths as values. All paths must be relative. |
|
|
94
97
|
| `preloads` | `object` | ✓ | Preload entries. It takes the name of the entries as keys and their paths as values. All paths must be relative. |
|
|
95
98
|
| `srcAlias` | `string` | ✗ | Custom [alias](https://webpack.js.org/configuration/resolve/#resolvealias) to the `src` folder.
|
|
@@ -104,12 +107,13 @@ At the root of your project, create a `rebuiltron.config.cjs` file.
|
|
|
104
107
|
|
|
105
108
|
```js
|
|
106
109
|
module.exports = {
|
|
110
|
+
main: "./electron/main.js",
|
|
107
111
|
renderers: {
|
|
108
112
|
app: "./src/app.js",
|
|
109
113
|
worker: "./src/worker.js"
|
|
110
114
|
},
|
|
111
115
|
preloads: {
|
|
112
|
-
|
|
116
|
+
app: "./electron/preloads/app.js"
|
|
113
117
|
},
|
|
114
118
|
srcAlias: "@app",
|
|
115
119
|
sassOptions: {
|
|
@@ -124,14 +128,27 @@ module.exports = {
|
|
|
124
128
|
> [!NOTE]
|
|
125
129
|
> Your renderers entry file(s) will be automatically injected into your HTML file(s). Thus, make sure you have a corresponding HTML file in the `public` folder for each entry (using the same name).
|
|
126
130
|
|
|
131
|
+
### Preloads
|
|
132
|
+
|
|
133
|
+
Since Rebuiltron will build the preload file(s) both in development and production, you can use a single path for both environment. Built files use the names declared in your configuration: `electron.preload.[name].js`.
|
|
134
|
+
|
|
135
|
+
```js
|
|
136
|
+
const appWindow = new BrowserWindow({
|
|
137
|
+
webPreferences: {
|
|
138
|
+
// Using the example configuration file above
|
|
139
|
+
preload: path.join(__dirname, "electron.preload.app.js"),
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
```
|
|
143
|
+
|
|
127
144
|
### Environment variables
|
|
128
145
|
|
|
129
146
|
When the development server is running, Rebuiltron exposes a `DEV_LOCAL_URL` variable that you can access on your main process using `process.env.DEV_LOCAL_URL`.
|
|
130
147
|
|
|
131
148
|
```js
|
|
132
|
-
|
|
133
|
-
appWindow.
|
|
134
|
-
}
|
|
149
|
+
app.isPackaged
|
|
150
|
+
? appWindow.loadFile(join(__dirname, "../../app.html")) // Prod
|
|
151
|
+
: appWindow.loadURL(`${process.env.DEV_LOCAL_URL}/app.html`); // Dev
|
|
135
152
|
```
|
|
136
153
|
|
|
137
154
|
## Usage
|
package/configurations/base.js
CHANGED
|
@@ -1,22 +1,12 @@
|
|
|
1
1
|
const { createHash } = require("crypto");
|
|
2
2
|
|
|
3
|
-
const HtmlWebpackPlugin = require("html-webpack-plugin");
|
|
4
3
|
const CaseSensitivePathsPlugin = require("case-sensitive-paths-webpack-plugin");
|
|
5
|
-
const InlineChunkHtmlPlugin = require("react-dev-utils/InlineChunkHtmlPlugin");
|
|
6
4
|
const TerserPlugin = require("terser-webpack-plugin");
|
|
7
|
-
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
|
8
|
-
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
|
|
9
5
|
const ModuleNotFoundPlugin = require("react-dev-utils/ModuleNotFoundPlugin");
|
|
10
|
-
const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin");
|
|
11
|
-
const CopyPlugin = require("copy-webpack-plugin");
|
|
12
6
|
|
|
13
7
|
const paths = require("../helpers/paths");
|
|
14
|
-
const {
|
|
8
|
+
const { isEnvDevelopment, isEnvProduction } = require("../helpers/environment");
|
|
15
9
|
const { emptyOr } = require("../helpers/utils");
|
|
16
|
-
const imageLoaders = require("../loaders/images");
|
|
17
|
-
const styleLoaders = require("../loaders/style");
|
|
18
|
-
const javascriptLoaders = require("../loaders/javascript");
|
|
19
|
-
const rebuiltronConfig = require("../rebuiltronConfig");
|
|
20
10
|
|
|
21
11
|
|
|
22
12
|
const { srcAlias } = require(paths.appConfig);
|
|
@@ -72,53 +62,14 @@ module.exports = {
|
|
|
72
62
|
comments: false
|
|
73
63
|
}
|
|
74
64
|
}
|
|
75
|
-
})
|
|
76
|
-
new CssMinimizerPlugin()
|
|
65
|
+
})
|
|
77
66
|
]
|
|
78
67
|
},
|
|
79
68
|
module: {
|
|
80
|
-
strictExportPresence: true
|
|
81
|
-
rules: [
|
|
82
|
-
// Handles `node_modules` packages that contain sourcemaps
|
|
83
|
-
...emptyOr(shouldUseSourceMap, [{
|
|
84
|
-
enforce: "pre",
|
|
85
|
-
exclude: /@babel(?:\/|\\{1,2})runtime/,
|
|
86
|
-
test: /\.(js|mjs|jsx|ts|tsx|css)$/,
|
|
87
|
-
loader: require.resolve("source-map-loader")
|
|
88
|
-
}]),
|
|
89
|
-
{
|
|
90
|
-
oneOf: [
|
|
91
|
-
...imageLoaders,
|
|
92
|
-
...javascriptLoaders,
|
|
93
|
-
...styleLoaders,
|
|
94
|
-
{
|
|
95
|
-
// Makes sure the assets get served by `WebpackDevServer`
|
|
96
|
-
exclude: [/^$/, /\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
|
|
97
|
-
type: "asset/resource"
|
|
98
|
-
}
|
|
99
|
-
]
|
|
100
|
-
}
|
|
101
|
-
]
|
|
69
|
+
strictExportPresence: true
|
|
102
70
|
},
|
|
103
71
|
plugins: [
|
|
104
|
-
...emptyOr(isEnvProduction, [
|
|
105
|
-
new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/runtime-.+[.]js/]), // Injects scripts into HTML
|
|
106
|
-
new MiniCssExtractPlugin({
|
|
107
|
-
filename: `${rebuiltronConfig.buildDirs.css}/[name].[contenthash:8].css`,
|
|
108
|
-
chunkFilename: `${rebuiltronConfig.buildDirs.css}/[name].[contenthash:8].chunk.css`
|
|
109
|
-
}),
|
|
110
|
-
new CopyPlugin({
|
|
111
|
-
patterns: [{
|
|
112
|
-
from: paths.appPublic,
|
|
113
|
-
to: paths.appBuild,
|
|
114
|
-
globOptions: {
|
|
115
|
-
ignore: ["**/*.html"]
|
|
116
|
-
}
|
|
117
|
-
}]
|
|
118
|
-
})
|
|
119
|
-
]),
|
|
120
72
|
...emptyOr(isEnvDevelopment, [
|
|
121
|
-
new ReactRefreshWebpackPlugin({ overlay: false }),
|
|
122
73
|
new CaseSensitivePathsPlugin() // Detects case errors in import paths
|
|
123
74
|
]),
|
|
124
75
|
new ModuleNotFoundPlugin(paths.appPath) // Gives some necessary context to module not found errors
|
package/configurations/main.js
CHANGED
|
@@ -1,16 +1,28 @@
|
|
|
1
1
|
const paths = require("../helpers/paths");
|
|
2
2
|
const rebuiltronConfig = require("../rebuiltronConfig");
|
|
3
3
|
const baseConfig = require("./base");
|
|
4
|
+
const javascriptLoaders = require("../loaders/javascript");
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
const { main } = require(paths.appConfig);
|
|
4
8
|
|
|
5
9
|
|
|
6
10
|
module.exports = {
|
|
7
11
|
...baseConfig,
|
|
8
12
|
target: "electron-main",
|
|
9
13
|
entry: {
|
|
10
|
-
[rebuiltronConfig.buildFileNames.main]:
|
|
14
|
+
[rebuiltronConfig.buildFileNames.main]: main
|
|
11
15
|
},
|
|
12
16
|
output: {
|
|
13
17
|
...baseConfig.output,
|
|
14
18
|
filename: `${rebuiltronConfig.buildDirs.js}/[name].js`
|
|
19
|
+
},
|
|
20
|
+
module: {
|
|
21
|
+
...baseConfig.module,
|
|
22
|
+
rules: [
|
|
23
|
+
{
|
|
24
|
+
oneOf: javascriptLoaders
|
|
25
|
+
}
|
|
26
|
+
]
|
|
15
27
|
}
|
|
16
28
|
};
|
|
@@ -3,6 +3,7 @@ const { mapKeys } = require("lodash");
|
|
|
3
3
|
const paths = require("../helpers/paths");
|
|
4
4
|
const rebuiltronConfig = require("../rebuiltronConfig");
|
|
5
5
|
const baseConfig = require("./base");
|
|
6
|
+
const javascriptLoaders = require("../loaders/javascript");
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
const { preloads } = require(paths.appConfig);
|
|
@@ -12,10 +13,18 @@ module.exports = {
|
|
|
12
13
|
...baseConfig,
|
|
13
14
|
target: "electron-preload",
|
|
14
15
|
entry: mapKeys(preloads, (_value, entryName) => (
|
|
15
|
-
`${rebuiltronConfig.buildFileNames.preload}.${entryName}`
|
|
16
|
-
),
|
|
16
|
+
`${rebuiltronConfig.buildFileNames.preload}.${entryName}`
|
|
17
|
+
)),
|
|
17
18
|
output: {
|
|
18
19
|
...baseConfig.output,
|
|
19
20
|
filename: `${rebuiltronConfig.buildDirs.js}/[name].js`
|
|
21
|
+
},
|
|
22
|
+
module: {
|
|
23
|
+
...baseConfig.module,
|
|
24
|
+
rules: [
|
|
25
|
+
{
|
|
26
|
+
oneOf: javascriptLoaders
|
|
27
|
+
}
|
|
28
|
+
]
|
|
20
29
|
}
|
|
21
30
|
};
|
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
const path = require("path");
|
|
2
2
|
|
|
3
3
|
const HtmlWebpackPlugin = require("html-webpack-plugin");
|
|
4
|
+
const CopyPlugin = require("copy-webpack-plugin");
|
|
5
|
+
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
|
6
|
+
const InlineChunkHtmlPlugin = require("react-dev-utils/InlineChunkHtmlPlugin");
|
|
7
|
+
const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin");
|
|
8
|
+
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
|
|
4
9
|
const { keys } = require("lodash");
|
|
5
10
|
|
|
6
11
|
const paths = require("../helpers/paths");
|
|
7
|
-
const { isEnvProduction, shouldUseSourceMap } = require("../helpers/environment");
|
|
12
|
+
const { isEnvProduction, isEnvDevelopment, shouldUseSourceMap } = require("../helpers/environment");
|
|
8
13
|
const { emptyOr } = require("../helpers/utils");
|
|
9
14
|
const rebuiltronConfig = require("../rebuiltronConfig");
|
|
10
15
|
const baseConfig = require("./base");
|
|
16
|
+
const imageLoaders = require("../loaders/images");
|
|
17
|
+
const styleLoaders = require("../loaders/style");
|
|
18
|
+
const javascriptLoaders = require("../loaders/javascript");
|
|
11
19
|
|
|
12
20
|
|
|
13
21
|
const { renderers } = require(paths.appConfig);
|
|
@@ -24,9 +32,59 @@ module.exports = {
|
|
|
24
32
|
chunkFilename: `${rebuiltronConfig.buildDirs.js}/${isEnvProduction ? "[name].[contenthash:8].chunk.js" : "[name].chunk.js"}`,
|
|
25
33
|
assetModuleFilename: `${rebuiltronConfig.buildDirs.media}/[name].[hash][ext]`
|
|
26
34
|
},
|
|
35
|
+
optimization: {
|
|
36
|
+
...baseConfig.optimization,
|
|
37
|
+
minimizer: [
|
|
38
|
+
...baseConfig.optimization.minimizer,
|
|
39
|
+
new CssMinimizerPlugin()
|
|
40
|
+
]
|
|
41
|
+
},
|
|
42
|
+
module: {
|
|
43
|
+
...baseConfig.module,
|
|
44
|
+
rules: [
|
|
45
|
+
// Handles `node_modules` packages that contain sourcemaps
|
|
46
|
+
...emptyOr(shouldUseSourceMap, [{
|
|
47
|
+
enforce: "pre",
|
|
48
|
+
exclude: /@babel(?:\/|\\{1,2})runtime/,
|
|
49
|
+
test: /\.(js|mjs|jsx|ts|tsx|css)$/,
|
|
50
|
+
loader: require.resolve("source-map-loader")
|
|
51
|
+
}]),
|
|
52
|
+
{
|
|
53
|
+
oneOf: [
|
|
54
|
+
...imageLoaders,
|
|
55
|
+
...javascriptLoaders,
|
|
56
|
+
...styleLoaders,
|
|
57
|
+
{
|
|
58
|
+
// Makes sure the assets get served by `WebpackDevServer`
|
|
59
|
+
exclude: [/^$/, /\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
|
|
60
|
+
type: "asset/resource"
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
},
|
|
27
66
|
plugins: [
|
|
28
67
|
...baseConfig.plugins,
|
|
29
|
-
...
|
|
68
|
+
...emptyOr(isEnvProduction, [
|
|
69
|
+
new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/runtime-.+[.]js/]), // Injects scripts into HTML
|
|
70
|
+
new MiniCssExtractPlugin({
|
|
71
|
+
filename: `${rebuiltronConfig.buildDirs.css}/[name].[contenthash:8].css`,
|
|
72
|
+
chunkFilename: `${rebuiltronConfig.buildDirs.css}/[name].[contenthash:8].chunk.css`
|
|
73
|
+
}),
|
|
74
|
+
new CopyPlugin({
|
|
75
|
+
patterns: [{
|
|
76
|
+
from: paths.appPublic,
|
|
77
|
+
to: paths.appBuild,
|
|
78
|
+
globOptions: {
|
|
79
|
+
ignore: ["**/*.html"]
|
|
80
|
+
}
|
|
81
|
+
}]
|
|
82
|
+
})
|
|
83
|
+
]),
|
|
84
|
+
...emptyOr(isEnvDevelopment, [
|
|
85
|
+
new ReactRefreshWebpackPlugin({ overlay: false })
|
|
86
|
+
]),
|
|
87
|
+
...keys(renderers).map((renderer) => (
|
|
30
88
|
new HtmlWebpackPlugin({
|
|
31
89
|
inject: true,
|
|
32
90
|
template: path.join(paths.appPublic, `${renderer}.html`),
|
package/helpers/paths.js
CHANGED
|
@@ -3,17 +3,11 @@ const { isEnvDevelopment } = require("./environment.js");
|
|
|
3
3
|
const { resolveApp } = require("./utils.js");
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
const packageJsonPath = resolveApp("package.json");
|
|
7
|
-
const packageJson = require(packageJsonPath);
|
|
8
|
-
|
|
9
|
-
|
|
10
6
|
module.exports = {
|
|
11
7
|
appConfig: resolveApp(rebuiltronConfig.configFileName),
|
|
12
|
-
electronMain: resolveApp(packageJson.main),
|
|
13
8
|
appPath: resolveApp("."),
|
|
14
9
|
appBuild: resolveApp(rebuiltronConfig.appDirs.build),
|
|
15
10
|
appPublic: resolveApp(rebuiltronConfig.appDirs.public),
|
|
16
|
-
appPackageJson: packageJsonPath,
|
|
17
11
|
src: resolveApp(rebuiltronConfig.appDirs.src),
|
|
18
12
|
appNodeModules: resolveApp("node_modules"),
|
|
19
13
|
appWebpackCache: resolveApp("node_modules/.cache"),
|
package/loaders/javascript.js
CHANGED
|
@@ -3,17 +3,6 @@ const { shouldUseSourceMap, isEnvProduction } = require("../helpers/environment"
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
module.exports = [
|
|
6
|
-
{
|
|
7
|
-
// Converts `import.meta.url` before SWC transpiles so paths using it stay dynamic
|
|
8
|
-
test: /\.js$/,
|
|
9
|
-
include: [paths.electronMain],
|
|
10
|
-
loader: require.resolve("string-replace-loader"),
|
|
11
|
-
options: {
|
|
12
|
-
search: "import.meta.url",
|
|
13
|
-
replace: "require('url').pathToFileURL(__filename).toString()",
|
|
14
|
-
flags: "g"
|
|
15
|
-
}
|
|
16
|
-
},
|
|
17
6
|
{
|
|
18
7
|
test: /\.(js|jsx)$/,
|
|
19
8
|
exclude: [paths.appNodeModules],
|
package/loaders/style.js
CHANGED
|
@@ -13,7 +13,7 @@ const { sassOptions } = require(paths.appConfig);
|
|
|
13
13
|
|
|
14
14
|
const _publicPath = rebuiltronConfig.buildDirs.css
|
|
15
15
|
.split("/")
|
|
16
|
-
.reduce(path => (path + "../"), "");
|
|
16
|
+
.reduce((path) => (path + "../"), "");
|
|
17
17
|
|
|
18
18
|
const _getBaseStyleLoaders = () => ([
|
|
19
19
|
...emptyOr(isEnvDevelopment, [require.resolve("style-loader")]),
|
package/package.json
CHANGED
|
@@ -1,50 +1,51 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rebuiltron",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.1",
|
|
4
4
|
"author": "Arkellys",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"bin":
|
|
6
|
+
"bin": {
|
|
7
|
+
"rebuiltron": "bin/index.js"
|
|
8
|
+
},
|
|
7
9
|
"scripts": {
|
|
8
10
|
"lint": "eslint ."
|
|
9
11
|
},
|
|
10
12
|
"devDependencies": {
|
|
11
13
|
"eslint": "^8.57.0",
|
|
12
|
-
"eslint-config-arklint": "^1.
|
|
14
|
+
"eslint-config-arklint": "^1.11.0"
|
|
13
15
|
},
|
|
14
16
|
"dependencies": {
|
|
15
|
-
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.
|
|
17
|
+
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.15",
|
|
16
18
|
"@svgr/webpack": "^8.1.0",
|
|
17
|
-
"@swc/core": "^1.
|
|
18
|
-
"browserslist": "^4.23.
|
|
19
|
+
"@swc/core": "^1.7.26",
|
|
20
|
+
"browserslist": "^4.23.3",
|
|
19
21
|
"case-sensitive-paths-webpack-plugin": "^2.4.0",
|
|
20
22
|
"copy-webpack-plugin": "^12.0.2",
|
|
21
|
-
"css-loader": "^7.1.
|
|
22
|
-
"css-minimizer-webpack-plugin": "^
|
|
23
|
-
"detect-port": "^1.
|
|
23
|
+
"css-loader": "^7.1.2",
|
|
24
|
+
"css-minimizer-webpack-plugin": "^7.0.0",
|
|
25
|
+
"detect-port": "^1.6.1",
|
|
24
26
|
"fs-extra": "^11.2.0",
|
|
25
27
|
"html-webpack-plugin": "^5.6.0",
|
|
26
28
|
"lodash": "^4.17.21",
|
|
27
|
-
"mini-css-extract-plugin": "^2.9.
|
|
28
|
-
"postcss": "^8.4.
|
|
29
|
+
"mini-css-extract-plugin": "^2.9.1",
|
|
30
|
+
"postcss": "^8.4.47",
|
|
29
31
|
"postcss-flexbugs-fixes": "^5.0.2",
|
|
30
32
|
"postcss-loader": "^8.1.1",
|
|
31
|
-
"postcss-normalize": "^
|
|
32
|
-
"postcss-preset-env": "^
|
|
33
|
+
"postcss-normalize": "^13.0.0",
|
|
34
|
+
"postcss-preset-env": "^10.0.3",
|
|
33
35
|
"react-dev-utils": "^12.0.1",
|
|
34
|
-
"react-refresh": "^0.14.
|
|
36
|
+
"react-refresh": "^0.14.2",
|
|
35
37
|
"resolve-url-loader": "^5.0.0",
|
|
36
|
-
"sass-loader": "^
|
|
38
|
+
"sass-loader": "^16.0.1",
|
|
37
39
|
"source-map-loader": "^5.0.0",
|
|
38
40
|
"spinnies": "^0.5.1",
|
|
39
|
-
"string-replace-loader": "^3.1.0",
|
|
40
41
|
"style-loader": "^4.0.0",
|
|
41
42
|
"swc-loader": "^0.2.6",
|
|
42
43
|
"terser-webpack-plugin": "^5.3.10",
|
|
43
|
-
"webpack": "^5.
|
|
44
|
-
"webpack-dev-server": "^5.0
|
|
44
|
+
"webpack": "^5.94.0",
|
|
45
|
+
"webpack-dev-server": "^5.1.0"
|
|
45
46
|
},
|
|
46
47
|
"peerDependencies": {
|
|
47
|
-
"electron": ">=
|
|
48
|
+
"electron": ">=32.0.0",
|
|
48
49
|
"react": ">=18.0.0",
|
|
49
50
|
"react-dom": ">=18.0.0"
|
|
50
51
|
},
|
package/rebuiltronConfig.js
CHANGED
package/scripts/build.js
CHANGED
|
@@ -3,14 +3,11 @@ process.env.NODE_ENV = "production";
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
const { measureFileSizesBeforeBuild, printFileSizesAfterBuild } = require("react-dev-utils/FileSizeReporter");
|
|
6
|
-
const { isEmpty } = require("lodash");
|
|
7
|
-
const clearConsole = require("react-dev-utils/clearConsole");
|
|
8
6
|
|
|
9
|
-
const
|
|
7
|
+
const buildApp = require("../tasks/buildApp");
|
|
8
|
+
const checkSetup = require("../tasks/checkSetup");
|
|
10
9
|
const paths = require("../helpers/paths");
|
|
11
10
|
const { exitProcessWithError } = require("../helpers/utils");
|
|
12
|
-
const log = require("../helpers/logger");
|
|
13
|
-
const spinnies = require("../helpers/spinnies");
|
|
14
11
|
|
|
15
12
|
|
|
16
13
|
process.on("unhandledRejection", exitProcessWithError);
|
|
@@ -20,19 +17,9 @@ const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024;
|
|
|
20
17
|
|
|
21
18
|
checkSetup
|
|
22
19
|
.then(() => measureFileSizesBeforeBuild(paths.appBuild))
|
|
23
|
-
.then(previousFileSizes =>
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
})
|
|
27
|
-
.then(({ stats, previousFileSizes, warnings }) => {
|
|
28
|
-
spinnies.remove("build");
|
|
29
|
-
clearConsole();
|
|
30
|
-
|
|
31
|
-
isEmpty(warnings)
|
|
32
|
-
? log.success("Compiled successfully!")
|
|
33
|
-
: log.warning(["Compiled with warnings.\n", warnings.join("\n\n")]);
|
|
34
|
-
|
|
35
|
-
console.log("File sizes after gzip:\n");
|
|
20
|
+
.then((previousFileSizes) => buildApp(previousFileSizes))
|
|
21
|
+
.then(({ stats, previousFileSizes }) => {
|
|
22
|
+
console.log("\nFile sizes after gzip:\n");
|
|
36
23
|
|
|
37
24
|
printFileSizesAfterBuild(
|
|
38
25
|
stats,
|
package/scripts/start.js
CHANGED
|
@@ -4,21 +4,25 @@ process.env.NODE_ENV = "development";
|
|
|
4
4
|
|
|
5
5
|
const clearConsole = require("react-dev-utils/clearConsole");
|
|
6
6
|
|
|
7
|
-
const checkSetup = require("../checkSetup");
|
|
7
|
+
const checkSetup = require("../tasks/checkSetup");
|
|
8
|
+
const startDevServer = require("../tasks/startDevServer");
|
|
9
|
+
const compileMain = require("../tasks/compileMain");
|
|
10
|
+
const watchPreloads = require("../tasks/watchPreloads");
|
|
11
|
+
const startElectron = require("../tasks/startElectron");
|
|
8
12
|
const { exitProcessWithError } = require("../helpers/utils");
|
|
9
|
-
const spinnies = require("../helpers/spinnies");
|
|
10
13
|
|
|
11
14
|
|
|
12
15
|
process.on("unhandledRejection", exitProcessWithError);
|
|
13
16
|
|
|
14
|
-
checkSetup.then(([port]) => {
|
|
15
|
-
const createDevServer = require("../createDevServer");
|
|
16
|
-
const devServer = createDevServer(port);
|
|
17
|
-
|
|
17
|
+
checkSetup.then(async ([port]) => {
|
|
18
18
|
clearConsole();
|
|
19
|
-
spinnies.add("devServer", { text: "Starting the development server" });
|
|
20
19
|
|
|
21
|
-
|
|
20
|
+
await watchPreloads();
|
|
21
|
+
await compileMain();
|
|
22
|
+
const devServer = await startDevServer(port);
|
|
23
|
+
await startElectron(port);
|
|
24
|
+
|
|
25
|
+
console.log();
|
|
22
26
|
|
|
23
27
|
["SIGINT", "SIGTERM"].forEach((sig) => {
|
|
24
28
|
process.on(sig, async () => {
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
const fsExtra = require("fs-extra");
|
|
2
|
+
const webpack = require("webpack");
|
|
3
|
+
const clearConsole = require("react-dev-utils/clearConsole");
|
|
4
|
+
const formatWebpackMessages = require("react-dev-utils/formatWebpackMessages");
|
|
5
|
+
const { bold, green, yellow } = require("chalk");
|
|
6
|
+
|
|
7
|
+
const paths = require("../helpers/paths");
|
|
8
|
+
const webpackConfig = require("../webpack.config");
|
|
9
|
+
const spinnies = require("../helpers/spinnies");
|
|
10
|
+
const log = require("../helpers/logger");
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Builds the app for production.
|
|
15
|
+
* @param {any} previousFileSizes - Size of the files of the previous build
|
|
16
|
+
* @returns {Promise<{ stats: webpack.Stats | undefined, previousFileSizes: any }>} Result of the build
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
module.exports = (previousFileSizes) => {
|
|
20
|
+
fsExtra.emptyDirSync(paths.appBuild);
|
|
21
|
+
const compiler = webpack(webpackConfig.production);
|
|
22
|
+
|
|
23
|
+
return new Promise((resolve, reject) => {
|
|
24
|
+
clearConsole();
|
|
25
|
+
spinnies.add("build", { text: "Creating the production build" });
|
|
26
|
+
|
|
27
|
+
compiler.run((error, stats) => {
|
|
28
|
+
if (!error) {
|
|
29
|
+
return resolve({
|
|
30
|
+
stats,
|
|
31
|
+
previousFileSizes
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
spinnies.fail("build", {
|
|
36
|
+
text: "Failed to compile"
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
reject(error);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
compiler.hooks.done.tap("done", (stats) => {
|
|
43
|
+
clearConsole();
|
|
44
|
+
|
|
45
|
+
const statsData = stats.toJson({ all: false, warnings: true, errors: true });
|
|
46
|
+
const { errors, warnings } = formatWebpackMessages(statsData);
|
|
47
|
+
|
|
48
|
+
if (stats.hasErrors()) throw new Error(errors);
|
|
49
|
+
|
|
50
|
+
if (stats.hasWarnings()) {
|
|
51
|
+
spinnies.update("build", {
|
|
52
|
+
text: `Compiled ${yellow(bold("with warnings"))}`,
|
|
53
|
+
status: "stopped",
|
|
54
|
+
color: "white"
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
return log.warning(warnings.join("\n\n"));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
spinnies.succeed("build", {
|
|
61
|
+
text: `Compiled ${green(bold("successfully"))}`
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
};
|
|
@@ -2,11 +2,12 @@ const fs = require("fs");
|
|
|
2
2
|
|
|
3
3
|
const detect = require("detect-port");
|
|
4
4
|
|
|
5
|
-
const { isEnvProduction } = require("
|
|
6
|
-
const rebuiltronConfig = require("
|
|
7
|
-
const { resolveApp } = require("
|
|
5
|
+
const { isEnvProduction } = require("../helpers/environment");
|
|
6
|
+
const rebuiltronConfig = require("../rebuiltronConfig");
|
|
7
|
+
const { resolveApp } = require("../helpers/utils");
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
+
* @type {Promise<number>}
|
|
10
11
|
* Checks whether the default port is available, otherwise resolves with the next available port.
|
|
11
12
|
*/
|
|
12
13
|
|
|
@@ -20,6 +21,7 @@ const checkPort = new Promise(async (resolve) => {
|
|
|
20
21
|
});
|
|
21
22
|
|
|
22
23
|
/**
|
|
24
|
+
* @type {Promise<void>}
|
|
23
25
|
* Checks whether Electron's entry point is set.
|
|
24
26
|
*/
|
|
25
27
|
|
|
@@ -38,6 +40,7 @@ const checkEntryPoint = new Promise((resolve, reject) => {
|
|
|
38
40
|
});
|
|
39
41
|
|
|
40
42
|
/**
|
|
43
|
+
* @type {Promise<void>}
|
|
41
44
|
* Checks whether Rebuiltron's config file exists and contains the required fields.
|
|
42
45
|
*/
|
|
43
46
|
|
|
@@ -51,8 +54,9 @@ const checkAppConfig = new Promise((resolve, reject) => {
|
|
|
51
54
|
]);
|
|
52
55
|
}
|
|
53
56
|
|
|
54
|
-
const { preloads, renderers } = require(configPath);
|
|
57
|
+
const { main, preloads, renderers } = require(configPath);
|
|
55
58
|
|
|
59
|
+
if (!main) reject("Configuration error: `main` field is required.");
|
|
56
60
|
if (!preloads) reject("Configuration error: `preloads` field is required.");
|
|
57
61
|
if (!renderers) reject("Configuration error: `renderers` field is required.");
|
|
58
62
|
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const webpack = require("webpack");
|
|
2
|
+
const { bold, green } = require("chalk");
|
|
3
|
+
const formatWebpackMessages = require("react-dev-utils/formatWebpackMessages");
|
|
4
|
+
|
|
5
|
+
const webpackConfig = require("../webpack.config");
|
|
6
|
+
const spinnies = require("../helpers/spinnies");
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Compiles main entry file for development.
|
|
11
|
+
* @returns {Promise<void>} Promise resolving when compilation is successful
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
module.exports = () => {
|
|
15
|
+
const mainCompiler = webpack(webpackConfig.development.main);
|
|
16
|
+
|
|
17
|
+
return new Promise((resolve, reject) => {
|
|
18
|
+
spinnies.add("compile-main", { text: "Compiling main file..." });
|
|
19
|
+
|
|
20
|
+
mainCompiler.run((error) => {
|
|
21
|
+
if (!error) return resolve();
|
|
22
|
+
|
|
23
|
+
spinnies.fail("compile-main", {
|
|
24
|
+
text: "Failed to compile main file"
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
reject(error);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
mainCompiler.hooks.done.tap("done", (stats) => {
|
|
31
|
+
const statsData = stats.toJson({ all: false, warnings: true, errors: true });
|
|
32
|
+
const { errors } = formatWebpackMessages(statsData);
|
|
33
|
+
|
|
34
|
+
if (stats.hasErrors()) throw new Error(errors);
|
|
35
|
+
|
|
36
|
+
spinnies.succeed("compile-main", {
|
|
37
|
+
text: `Main file compiled ${green(bold("successfully"))}`
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const webpack = require("webpack");
|
|
2
|
+
const WebpackDevServer = require("webpack-dev-server");
|
|
3
|
+
const clearConsole = require("react-dev-utils/clearConsole");
|
|
4
|
+
const { bold } = require("chalk");
|
|
5
|
+
|
|
6
|
+
const webpackConfig = require("../webpack.config");
|
|
7
|
+
const devServerConfig = require("../webpackDevServer.config");
|
|
8
|
+
const spinnies = require("../helpers/spinnies");
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Starts the development server.
|
|
12
|
+
* @param {number} port - Port on which the renderers are served
|
|
13
|
+
* @returns {Promise<WebpackDevServer>} Development server instance
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
module.exports = (port) => (
|
|
17
|
+
new Promise(async (resolve) => {
|
|
18
|
+
let devServer;
|
|
19
|
+
let isFirstRun = true;
|
|
20
|
+
|
|
21
|
+
const rendererCompiler = webpack(webpackConfig.development.renderers);
|
|
22
|
+
|
|
23
|
+
spinnies.add("devServer", { text: "Starting the development server" });
|
|
24
|
+
|
|
25
|
+
rendererCompiler.hooks.invalid.tap("invalid", () => {
|
|
26
|
+
clearConsole();
|
|
27
|
+
spinnies.add("compile", { text: "Compiling..." });
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
rendererCompiler.hooks.done.tap("done", () => {
|
|
31
|
+
if (isFirstRun) {
|
|
32
|
+
isFirstRun = false;
|
|
33
|
+
|
|
34
|
+
spinnies.succeed("devServer", { text: `Development server running on port ${bold(port)}` });
|
|
35
|
+
return resolve(devServer);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
clearConsole();
|
|
39
|
+
spinnies.remove("compile");
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
devServer = new WebpackDevServer({ ...devServerConfig, port }, rendererCompiler);
|
|
43
|
+
await devServer.start();
|
|
44
|
+
})
|
|
45
|
+
);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const { spawn } = require("child_process");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
|
|
5
|
+
const spinnies = require("../helpers/spinnies");
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Starts Electron.
|
|
10
|
+
* @param {number} port - Port on which the renderer is served
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
module.exports = (port) => (
|
|
14
|
+
new Promise((resolve, reject) => {
|
|
15
|
+
spinnies.add("electron", { text: "Starting Electron" });
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
const electronPath = require.resolve("electron");
|
|
19
|
+
const electronModulePath = path.dirname(electronPath);
|
|
20
|
+
const pathFile = path.join(electronModulePath, "path.txt");
|
|
21
|
+
const executablePath = fs.readFileSync(pathFile, "utf-8");
|
|
22
|
+
const electronExtPath = path.join(electronModulePath, "dist", executablePath);
|
|
23
|
+
|
|
24
|
+
spawn(electronExtPath, ["."], {
|
|
25
|
+
stdio: "inherit",
|
|
26
|
+
env: {
|
|
27
|
+
...process.env,
|
|
28
|
+
DEV_LOCAL_URL: `http://localhost:${port}`
|
|
29
|
+
}
|
|
30
|
+
}).on("close", process.exit);
|
|
31
|
+
|
|
32
|
+
spinnies.succeed("electron", { text: "Electron started" });
|
|
33
|
+
resolve();
|
|
34
|
+
|
|
35
|
+
} catch (error) {
|
|
36
|
+
spinnies.fail("electron", { text: "Failed to start Electron" });
|
|
37
|
+
reject(error);
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
);
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
const webpack = require("webpack");
|
|
2
|
+
const { red, bold, green, yellow } = require("chalk");
|
|
3
|
+
const formatWebpackMessages = require("react-dev-utils/formatWebpackMessages");
|
|
4
|
+
const clearConsole = require("react-dev-utils/clearConsole");
|
|
5
|
+
|
|
6
|
+
const webpackConfig = require("../webpack.config");
|
|
7
|
+
const spinnies = require("../helpers/spinnies");
|
|
8
|
+
const log = require("../helpers/logger");
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Sets up the watcher of preload files.
|
|
13
|
+
* @returns {Promise<void>} Promise resolving when compilation is successful
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
module.exports = () => {
|
|
17
|
+
const preloadCompiler = webpack(webpackConfig.development.preloads);
|
|
18
|
+
|
|
19
|
+
return new Promise((resolve, reject) => {
|
|
20
|
+
let isFirstWatch = true;
|
|
21
|
+
|
|
22
|
+
preloadCompiler.watch({}, (error) => {
|
|
23
|
+
if (!isFirstWatch) return;
|
|
24
|
+
isFirstWatch = false;
|
|
25
|
+
|
|
26
|
+
if (!error) return resolve();
|
|
27
|
+
|
|
28
|
+
spinnies.fail("watch", {
|
|
29
|
+
text: "Failed to compile preload file(s)"
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
reject(error);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
preloadCompiler.hooks.compile.tap("compile", () => {
|
|
36
|
+
if (!isFirstWatch) clearConsole();
|
|
37
|
+
|
|
38
|
+
spinnies.add("watch", {
|
|
39
|
+
text: "Compiling preload file(s)..."
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
preloadCompiler.hooks.done.tap("done", (stats) => {
|
|
44
|
+
const statsData = stats.toJson({ all: false, warnings: true, errors: true });
|
|
45
|
+
const { errors, warnings } = formatWebpackMessages(statsData);
|
|
46
|
+
|
|
47
|
+
if (stats.hasErrors()) {
|
|
48
|
+
if (isFirstWatch) throw new Error(errors); // Stops the process
|
|
49
|
+
|
|
50
|
+
spinnies.fail("watch", {
|
|
51
|
+
text: `Preload file(s) compiled ${red(bold("with errors"))}`,
|
|
52
|
+
failColor: "white"
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
return log.error(errors.join("\n\n"));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (stats.hasWarnings()) {
|
|
59
|
+
spinnies.update("watch", {
|
|
60
|
+
text: `Preload file(s) compiled ${yellow(bold("with warnings"))}`,
|
|
61
|
+
status: "stopped",
|
|
62
|
+
color: "white"
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
return log.warning(warnings.join("\n\n"));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
spinnies.succeed("watch", {
|
|
69
|
+
text: `Preload file(s) compiled ${green(bold("successfully"))}`
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
};
|
package/webpack.config.js
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
const { isEnvDevelopment } = require("./helpers/environment");
|
|
2
1
|
const rendererConfig = require("./configurations/renderers");
|
|
3
2
|
const preloadConfig = require("./configurations/preloads");
|
|
4
3
|
const mainConfig = require("./configurations/main");
|
|
5
4
|
|
|
6
5
|
|
|
7
|
-
module.exports =
|
|
6
|
+
module.exports = {
|
|
7
|
+
development: {
|
|
8
|
+
renderers: rendererConfig,
|
|
9
|
+
main: mainConfig,
|
|
10
|
+
preloads: preloadConfig
|
|
11
|
+
},
|
|
12
|
+
production: [rendererConfig, mainConfig, preloadConfig]
|
|
13
|
+
};
|
package/buildApp.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
const fsExtra = require("fs-extra");
|
|
2
|
-
const clearConsole = require("react-dev-utils/clearConsole");
|
|
3
|
-
const webpack = require("webpack");
|
|
4
|
-
const formatWebpackMessages = require("react-dev-utils/formatWebpackMessages");
|
|
5
|
-
const { isEmpty, head } = require("lodash");
|
|
6
|
-
|
|
7
|
-
const paths = require("./helpers/paths");
|
|
8
|
-
const webpackConfig = require("./webpack.config");
|
|
9
|
-
const spinnies = require("./helpers/spinnies");
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
module.exports = (previousFileSizes) => {
|
|
13
|
-
fsExtra.emptyDirSync(paths.appBuild);
|
|
14
|
-
|
|
15
|
-
clearConsole();
|
|
16
|
-
spinnies.add("build", { text: "Creating the production build" });
|
|
17
|
-
|
|
18
|
-
const compiler = webpack(webpackConfig);
|
|
19
|
-
|
|
20
|
-
return new Promise((resolve, reject) => {
|
|
21
|
-
compiler.run((error, stats) => {
|
|
22
|
-
const statsData = error
|
|
23
|
-
? { errors: [error?.message || error], warnings: [] }
|
|
24
|
-
: stats.toJson({ all: false, warnings: true, errors: true });
|
|
25
|
-
|
|
26
|
-
const { errors, warnings } = formatWebpackMessages(statsData);
|
|
27
|
-
|
|
28
|
-
return !isEmpty(errors)
|
|
29
|
-
? reject(["Failed to compile.\n", head(errors)])
|
|
30
|
-
: resolve({ stats, previousFileSizes, warnings });
|
|
31
|
-
});
|
|
32
|
-
});
|
|
33
|
-
};
|
package/createDevServer.js
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
const { spawn } = require("child_process");
|
|
2
|
-
const path = require("path");
|
|
3
|
-
const fs = require("fs");
|
|
4
|
-
|
|
5
|
-
const webpack = require("webpack");
|
|
6
|
-
const WebpackDevServer = require("webpack-dev-server");
|
|
7
|
-
const clearConsole = require("react-dev-utils/clearConsole");
|
|
8
|
-
const { bold } = require("chalk");
|
|
9
|
-
|
|
10
|
-
const webpackConfig = require("./webpack.config");
|
|
11
|
-
const devServerConfig = require("./webpackDevServer.config");
|
|
12
|
-
const { exitProcessWithError } = require("./helpers/utils");
|
|
13
|
-
const spinnies = require("./helpers/spinnies");
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
let isElectronStarted = false;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const _startElectron = (port) => {
|
|
20
|
-
spinnies.add("electron", { text: "Starting Electron" });
|
|
21
|
-
|
|
22
|
-
try {
|
|
23
|
-
const electronPath = require.resolve("electron");
|
|
24
|
-
const electronModulePath = path.dirname(electronPath);
|
|
25
|
-
const pathFile = path.join(electronModulePath, "path.txt");
|
|
26
|
-
const executablePath = fs.readFileSync(pathFile, "utf-8");
|
|
27
|
-
const electronExtPath = path.join(electronModulePath, "dist", executablePath);
|
|
28
|
-
|
|
29
|
-
spawn(electronExtPath, ["."], {
|
|
30
|
-
stdio: "inherit",
|
|
31
|
-
env: {
|
|
32
|
-
...process.env,
|
|
33
|
-
DEV_LOCAL_URL: `http://localhost:${port}`
|
|
34
|
-
}
|
|
35
|
-
}).on("close", process.exit);
|
|
36
|
-
|
|
37
|
-
spinnies.succeed("devServer", { text: `Development server running on port ${bold(port)}` });
|
|
38
|
-
spinnies.succeed("electron", { text: "Electron started\n" });
|
|
39
|
-
|
|
40
|
-
isElectronStarted = true;
|
|
41
|
-
|
|
42
|
-
} catch (error) {
|
|
43
|
-
exitProcessWithError({
|
|
44
|
-
message: [
|
|
45
|
-
"An error occurred while starting Electron.",
|
|
46
|
-
"Please make sure the dependency `electron` is installed."
|
|
47
|
-
],
|
|
48
|
-
stack: error.stack || error
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
module.exports = (port) => {
|
|
54
|
-
const compiler = webpack(webpackConfig);
|
|
55
|
-
|
|
56
|
-
// Starting (re)compiling
|
|
57
|
-
|
|
58
|
-
compiler.hooks.invalid.tap("invalid", () => {
|
|
59
|
-
clearConsole();
|
|
60
|
-
spinnies.add("compile", { text: "Compiling..." });
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
// Finished (re)compiling
|
|
64
|
-
|
|
65
|
-
compiler.hooks.done.tap("done", () => {
|
|
66
|
-
clearConsole();
|
|
67
|
-
spinnies.remove("compile");
|
|
68
|
-
|
|
69
|
-
if (!isElectronStarted) _startElectron(port);
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
return new WebpackDevServer({ ...devServerConfig, port }, compiler);
|
|
73
|
-
};
|