@norejs/ssr-builder 0.0.2 → 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.
- package/.turbo/turbo-build.log +5 -0
- package/CHANGELOG.md +19 -0
- package/README.md +5 -0
- package/package.json +28 -20
- package/plugins/modern/index.js +42 -0
- package/plugins/react-scripts-ssr/config/webpack.ssr.config.js +8 -6
- package/plugins/react-scripts-ssr/index.js +12 -10
- package/scripts/start.js +2 -2
- package/utils/{runWebpack.js → run-webpack.js} +6 -45
- package/utils/project.js +0 -128
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# @norejs/ssr-builder
|
|
2
|
+
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- update
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies
|
|
12
|
+
- @norejs/ssr-server@1.0.0
|
|
13
|
+
|
|
14
|
+
## 0.0.3
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- Updated dependencies [2a8b808]
|
|
19
|
+
- @norejs/ssr-server@0.1.0
|
package/README.md
ADDED
package/package.json
CHANGED
|
@@ -1,21 +1,29 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
2
|
+
"name": "@norejs/ssr-builder",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "SSR builder for NoreJS",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"norejs-ssr-builder": "./bin/norejs-ssr-builder.js"
|
|
8
|
+
},
|
|
9
|
+
"author": "pengzai",
|
|
10
|
+
"license": "ISC",
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@modern-js/builder": "^2.27.0",
|
|
13
|
+
"@modern-js/builder-rspack-provider": "^2.27.0",
|
|
14
|
+
"@modern-js/builder-webpack-provider": "^2.27.0",
|
|
15
|
+
"@norejs/ssr-server": "^1.0.0",
|
|
16
|
+
"@norejs/ssr-utils": "^0.0.2",
|
|
17
|
+
"commander": "10",
|
|
18
|
+
"fs-extra": "^11.1.1",
|
|
19
|
+
"mini-css-extract-plugin": "^2.7.6",
|
|
20
|
+
"react-dev-utils": "^12.0.1",
|
|
21
|
+
"webpack-merge": "^5.9.0",
|
|
22
|
+
"webpack-node-externals": "^3.0.0"
|
|
23
|
+
},
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "echo build",
|
|
26
|
+
"start": "echo start",
|
|
27
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const { createBuilder } = require('@modern-js/builder');
|
|
2
|
+
const {
|
|
3
|
+
builderWebpackProvider,
|
|
4
|
+
} = require('@modern-js/builder-webpack-provider');
|
|
5
|
+
// const nodeExternals = require('webpack-node-externals');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const projectRoot = process.cwd();
|
|
8
|
+
|
|
9
|
+
module.exports = async function start(
|
|
10
|
+
options,
|
|
11
|
+
ssrConfig,
|
|
12
|
+
webpackEnv = 'development'
|
|
13
|
+
) {
|
|
14
|
+
// 使用modern builder 构建项目
|
|
15
|
+
const provider = builderWebpackProvider({
|
|
16
|
+
builderConfig: {
|
|
17
|
+
output: {
|
|
18
|
+
distPath: {
|
|
19
|
+
root: ssrConfig.dist,
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
tools: {
|
|
23
|
+
webpack: (config, { env }) => {
|
|
24
|
+
console.log('webpack config', config);
|
|
25
|
+
config.output.libraryTarget = 'commonjs';
|
|
26
|
+
// config.externals = [nodeExternals()];
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
// some configs
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
const builder = await createBuilder(provider, {
|
|
33
|
+
cwd: process.cwd(),
|
|
34
|
+
entry: { main: path.resolve(projectRoot, ssrConfig.entry) },
|
|
35
|
+
target: 'node',
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
await builder.build({
|
|
39
|
+
mode: webpackEnv,
|
|
40
|
+
watch: webpackEnv === 'development',
|
|
41
|
+
});
|
|
42
|
+
};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
2
|
const nodeExternals = require('webpack-node-externals');
|
|
3
|
-
|
|
4
3
|
const { merge } = require('webpack-merge');
|
|
5
|
-
const
|
|
4
|
+
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
|
5
|
+
|
|
6
|
+
|
|
6
7
|
// 去掉HTMLWebpackPlugin
|
|
7
8
|
const ssrDisablePlugins = [
|
|
8
9
|
'HtmlWebpackPlugin',
|
|
@@ -13,16 +14,15 @@ const ssrDisablePlugins = [
|
|
|
13
14
|
'ReactRefreshWebpackPlugin',
|
|
14
15
|
];
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
|
|
17
18
|
|
|
18
19
|
module.exports = function (baseConfig, ssrConfig, webpackEnv = 'development') {
|
|
19
|
-
console.log('baseConfig', baseConfig);
|
|
20
20
|
// 去掉多余的插件
|
|
21
21
|
baseConfig.plugins = baseConfig.plugins.filter((plugin) => {
|
|
22
22
|
return !ssrDisablePlugins.includes(plugin.constructor.name);
|
|
23
23
|
});
|
|
24
24
|
if (
|
|
25
|
-
baseConfig.plugins.find(
|
|
25
|
+
!baseConfig.plugins.find(
|
|
26
26
|
(plugin) => plugin.constructor.name === 'MiniCssExtractPlugin'
|
|
27
27
|
)
|
|
28
28
|
) {
|
|
@@ -59,7 +59,7 @@ module.exports = function (baseConfig, ssrConfig, webpackEnv = 'development') {
|
|
|
59
59
|
});
|
|
60
60
|
|
|
61
61
|
// 读取env文件,或者自定义
|
|
62
|
-
|
|
62
|
+
const ssrWebpackConfig = merge(baseConfig, {
|
|
63
63
|
entry: { main: path.resolve(projectRoot, ssrConfig.entry) },
|
|
64
64
|
output: {
|
|
65
65
|
filename: 'server.js',
|
|
@@ -74,4 +74,6 @@ module.exports = function (baseConfig, ssrConfig, webpackEnv = 'development') {
|
|
|
74
74
|
target: 'node',
|
|
75
75
|
externals: [nodeExternals()],
|
|
76
76
|
});
|
|
77
|
+
console.log('ssrWebpackConfig', ssrWebpackConfig);
|
|
78
|
+
return ssrWebpackConfig;
|
|
77
79
|
};
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
const fs = require('fs-extra');
|
|
2
|
-
const {
|
|
3
|
-
getNpmPathFromCwd,
|
|
4
|
-
getFilePathFromCwd,
|
|
5
|
-
} = require('../../utils/project');
|
|
2
|
+
const { getNpmPathFromCwd, getFilePathFromCwd } = require('@norejs/ssr-utils');
|
|
6
3
|
|
|
7
|
-
const runWebpack = require('../../utils/
|
|
4
|
+
const runWebpack = require('../../utils/run-webpack');
|
|
8
5
|
|
|
9
6
|
module.exports = function start(
|
|
10
7
|
options,
|
|
@@ -13,9 +10,16 @@ module.exports = function start(
|
|
|
13
10
|
) {
|
|
14
11
|
process.env.NODE_ENV = webpackEnv;
|
|
15
12
|
process.env.BABEL_ENV = webpackEnv;
|
|
13
|
+
const isDev = webpackEnv === 'development';
|
|
16
14
|
// 获取react-scripts 的配置
|
|
17
|
-
const projectWebpackConfigPath =
|
|
18
|
-
|
|
15
|
+
const projectWebpackConfigPath =
|
|
16
|
+
getWebpackFile('webpack.config.js') ||
|
|
17
|
+
getWebpackFile('webpack.config.' + (isDev ? 'dev' : 'prod') + '.js');
|
|
18
|
+
console.log('projectWebpackConfigPath', projectWebpackConfigPath);
|
|
19
|
+
let baseWebpackConfig = require(projectWebpackConfigPath);
|
|
20
|
+
if (typeof baseWebpackConfig === 'function') {
|
|
21
|
+
baseWebpackConfig = baseWebpackConfig(webpackEnv);
|
|
22
|
+
}
|
|
19
23
|
const ssrWebpackConfigFactory = getSSRWebpackConfig();
|
|
20
24
|
if (typeof ssrWebpackConfigFactory !== 'function') {
|
|
21
25
|
throw new Error('webpack.ssr.config.js should export a function');
|
|
@@ -56,9 +60,7 @@ function getWebpackFile(webpackFileName) {
|
|
|
56
60
|
'react-scripts/config/' + webpackFileName
|
|
57
61
|
);
|
|
58
62
|
if (!fs.existsSync(webpackConfigPath)) {
|
|
59
|
-
|
|
60
|
-
'react-scripts is not installed in your project please make sure you have installed it'
|
|
61
|
-
);
|
|
63
|
+
return null;
|
|
62
64
|
}
|
|
63
65
|
return webpackConfigPath;
|
|
64
66
|
}
|
package/scripts/start.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// 读取项目中的配置,监测当前项目是否react-scripts 项目
|
|
2
|
-
const { getProjectConfig } = require('
|
|
2
|
+
const { getProjectConfig } = require('@norejs/ssr-utils');
|
|
3
3
|
|
|
4
4
|
module.exports = function start(options, webpackEnv = 'development') {
|
|
5
5
|
const config = getProjectConfig();
|
|
6
6
|
if (config.ssr) {
|
|
7
|
-
const builderName = config.ssr.builder || '
|
|
7
|
+
const builderName = config.ssr.builder || 'modern';
|
|
8
8
|
const builder = require(`../plugins/${builderName}`);
|
|
9
9
|
return builder(options, config.ssr, webpackEnv);
|
|
10
10
|
}
|
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
const { requireNpmFromCwd } = require('
|
|
2
|
-
const formatWebpackMessages = requireNpmFromCwd(
|
|
3
|
-
'react-dev-utils/formatWebpackMessages'
|
|
4
|
-
);
|
|
5
|
-
const chalk = requireNpmFromCwd('react-dev-utils/chalk');
|
|
6
|
-
const printBuildError = requireNpmFromCwd('react-dev-utils/printBuildError');
|
|
1
|
+
const { requireNpmFromCwd } = require('@norejs/ssr-utils');
|
|
7
2
|
const webpack = requireNpmFromCwd('webpack');
|
|
3
|
+
const chalk = require('react-dev-utils/chalk');
|
|
4
|
+
const formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
|
|
5
|
+
const printBuildError = require('react-dev-utils/printBuildError');
|
|
8
6
|
|
|
9
7
|
// TODO:展示进度条
|
|
10
8
|
// TODO: 展示结果
|
|
11
|
-
module.exports = function runWebpack(config, webpackEnv = 'development') {
|
|
9
|
+
module.exports = function runWebpack(config, webpackEnv = 'development', cb) {
|
|
12
10
|
const isDev = webpackEnv === 'development';
|
|
13
|
-
isDev ? start(config) : build(config);
|
|
11
|
+
isDev ? start(config, cb) : build(config, cb);
|
|
14
12
|
};
|
|
15
13
|
function start(config) {
|
|
16
14
|
const compiler = webpack(config);
|
|
@@ -34,23 +32,13 @@ function start(config) {
|
|
|
34
32
|
function build(config) {
|
|
35
33
|
const compiler = webpack(config);
|
|
36
34
|
return new Promise((resolve, reject) => {
|
|
37
|
-
console.log('SSR Compiling...');
|
|
38
35
|
compiler.run((err, stats) => {
|
|
39
36
|
let messages;
|
|
40
37
|
if (err) {
|
|
41
38
|
if (!err.message) {
|
|
42
39
|
return reject(err);
|
|
43
40
|
}
|
|
44
|
-
|
|
45
41
|
let errMessage = err.message;
|
|
46
|
-
|
|
47
|
-
// Add additional information for postcss errors
|
|
48
|
-
if (Object.prototype.hasOwnProperty.call(err, 'postcssNode')) {
|
|
49
|
-
errMessage +=
|
|
50
|
-
'\nCompileError: Begins at CSS selector ' +
|
|
51
|
-
err['postcssNode'].selector;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
42
|
messages = formatWebpackMessages({
|
|
55
43
|
errors: [errMessage],
|
|
56
44
|
warnings: [],
|
|
@@ -65,28 +53,11 @@ function build(config) {
|
|
|
65
53
|
);
|
|
66
54
|
}
|
|
67
55
|
if (messages.errors.length) {
|
|
68
|
-
// Only keep the first error. Others are often indicative
|
|
69
|
-
// of the same problem, but confuse the reader with noise.
|
|
70
56
|
if (messages.errors.length > 1) {
|
|
71
57
|
messages.errors.length = 1;
|
|
72
58
|
}
|
|
73
59
|
return reject(new Error(messages.errors.join('\n\n')));
|
|
74
60
|
}
|
|
75
|
-
if (
|
|
76
|
-
process.env.CI &&
|
|
77
|
-
(typeof process.env.CI !== 'string' ||
|
|
78
|
-
process.env.CI.toLowerCase() !== 'false') &&
|
|
79
|
-
messages.warnings.length
|
|
80
|
-
) {
|
|
81
|
-
console.log(
|
|
82
|
-
chalk.yellow(
|
|
83
|
-
'\nTreating warnings as errors because process.env.CI = true.\n' +
|
|
84
|
-
'Most CI servers set it automatically.\n'
|
|
85
|
-
)
|
|
86
|
-
);
|
|
87
|
-
return reject(new Error(messages.warnings.join('\n\n')));
|
|
88
|
-
}
|
|
89
|
-
|
|
90
61
|
const resolveArgs = {
|
|
91
62
|
stats,
|
|
92
63
|
previousFileSizes: 0,
|
|
@@ -100,16 +71,6 @@ function build(config) {
|
|
|
100
71
|
if (warnings.length) {
|
|
101
72
|
console.log(chalk.yellow('Compiled with warnings.\n'));
|
|
102
73
|
console.log(warnings.join('\n\n'));
|
|
103
|
-
console.log(
|
|
104
|
-
'\nSearch for the ' +
|
|
105
|
-
chalk.underline(chalk.yellow('keywords')) +
|
|
106
|
-
' to learn more about each warning.'
|
|
107
|
-
);
|
|
108
|
-
console.log(
|
|
109
|
-
'To ignore, add ' +
|
|
110
|
-
chalk.cyan('// eslint-disable-next-line') +
|
|
111
|
-
' to the line before.\n'
|
|
112
|
-
);
|
|
113
74
|
} else {
|
|
114
75
|
console.log(chalk.green('Compiled successfully.\n'));
|
|
115
76
|
}
|
package/utils/project.js
DELETED
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
const path = require('path');
|
|
2
|
-
const fs = require('fs-extra');
|
|
3
|
-
const defaultConfig = {
|
|
4
|
-
ssr: {
|
|
5
|
-
entry: 'src/server.js',
|
|
6
|
-
dist: 'build-ssr',
|
|
7
|
-
builder: 'react-scripts-ssr',
|
|
8
|
-
},
|
|
9
|
-
csr: {
|
|
10
|
-
dist: 'build',
|
|
11
|
-
},
|
|
12
|
-
};
|
|
13
|
-
/**
|
|
14
|
-
* 获取项目中的npm包路径
|
|
15
|
-
* @param {*} npmPkgName
|
|
16
|
-
* @param {*} filePath
|
|
17
|
-
* @returns
|
|
18
|
-
*/
|
|
19
|
-
function getNpmPathFromCwd(npmPkgName) {
|
|
20
|
-
const projectRoot = process.cwd();
|
|
21
|
-
const nodeModules = path.resolve(projectRoot, 'node_modules');
|
|
22
|
-
const npmPkgPath = path.resolve(nodeModules, npmPkgName);
|
|
23
|
-
return npmPkgPath;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
*
|
|
28
|
-
* @param {*} filePath
|
|
29
|
-
* @returns
|
|
30
|
-
*/
|
|
31
|
-
function getFilePathFromCwd(filePath) {
|
|
32
|
-
const projectRoot = process.cwd();
|
|
33
|
-
return path.resolve(projectRoot, filePath);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
async function isReactScriptsInstalled() {
|
|
37
|
-
const reactScriptsPath = getNpmPathFromCwd('react-scripts');
|
|
38
|
-
return await fs.exists(reactScriptsPath);
|
|
39
|
-
}
|
|
40
|
-
function getProjectConfig() {
|
|
41
|
-
const projectConfigPath = getFilePathFromCwd('nore.config.js');
|
|
42
|
-
let customConfig = {};
|
|
43
|
-
if (fs.existsSync(projectConfigPath)) {
|
|
44
|
-
customConfig = require(projectConfigPath) || {};
|
|
45
|
-
}
|
|
46
|
-
// 深度合并
|
|
47
|
-
// 深度合并
|
|
48
|
-
|
|
49
|
-
return deepAssign({}, defaultConfig, customConfig);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function isPlainObject(obj) {
|
|
53
|
-
return (
|
|
54
|
-
typeof obj === 'object' &&
|
|
55
|
-
Object.prototype.toString.call(obj) === '[object Object]'
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
function deepAssign() {
|
|
59
|
-
let len = arguments.length,
|
|
60
|
-
target = arguments[0];
|
|
61
|
-
if (!isPlainObject(target)) {
|
|
62
|
-
target = {};
|
|
63
|
-
}
|
|
64
|
-
for (let i = 1; i < len; i++) {
|
|
65
|
-
let source = arguments[i];
|
|
66
|
-
if (isPlainObject(source)) {
|
|
67
|
-
for (let s in source) {
|
|
68
|
-
if (s === '__proto__' || target === source[s]) {
|
|
69
|
-
continue;
|
|
70
|
-
}
|
|
71
|
-
if (isPlainObject(source[s])) {
|
|
72
|
-
target[s] = deepAssign(target[s], source[s]);
|
|
73
|
-
} else {
|
|
74
|
-
target[s] = source[s];
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
return target;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* 当前项目是否运行过eject
|
|
84
|
-
* @param {*} projectRoot
|
|
85
|
-
* @returns
|
|
86
|
-
*/
|
|
87
|
-
async function isEjected(projectRoot) {
|
|
88
|
-
const configPath = path.resolve(projectRoot, 'config');
|
|
89
|
-
const scriptsPath = path.resolve(projectRoot, 'scripts');
|
|
90
|
-
return (await fs.exists(configPath)) && (await fs.exists(scriptsPath));
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* 从项目中加载npm包
|
|
94
|
-
* @param {*} npmPkgName
|
|
95
|
-
* @returns
|
|
96
|
-
*/
|
|
97
|
-
function requireNpmFromCwd(npmPkgName) {
|
|
98
|
-
const nodeModules = getNpmPathFromCwd(npmPkgName);
|
|
99
|
-
try {
|
|
100
|
-
return require(nodeModules);
|
|
101
|
-
} catch (error) {
|
|
102
|
-
return undefined;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* 从项目中加载某个文件
|
|
108
|
-
* @param {*} filename
|
|
109
|
-
* @returns
|
|
110
|
-
*/
|
|
111
|
-
function requireFromCwd(filename) {
|
|
112
|
-
const nodeModules = getFilePathFromCwd(filename);
|
|
113
|
-
try {
|
|
114
|
-
return require(nodeModules);
|
|
115
|
-
} catch (error) {
|
|
116
|
-
return undefined;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
module.exports = {
|
|
121
|
-
getNpmPathFromCwd,
|
|
122
|
-
isEjected,
|
|
123
|
-
requireNpmFromCwd,
|
|
124
|
-
getFilePathFromCwd,
|
|
125
|
-
requireFromCwd,
|
|
126
|
-
getProjectConfig,
|
|
127
|
-
isReactScriptsInstalled,
|
|
128
|
-
};
|