nsbp-cli 0.1.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/CHANGELOG.md +102 -0
- package/README.md +150 -0
- package/bin/nsbp.js +145 -0
- package/package.json +43 -0
- package/scripts/sync-template.js +277 -0
- package/templates/basic/.prettierignore +5 -0
- package/templates/basic/.prettierrc +5 -0
- package/templates/basic/README.md +13 -0
- package/templates/basic/package.json +101 -0
- package/templates/basic/postcss.config.js +7 -0
- package/templates/basic/public/favicon.ico +0 -0
- package/templates/basic/public/images/test/0.jpg +0 -0
- package/templates/basic/public/images/test/1.jpg +0 -0
- package/templates/basic/public/images/test/2.jpg +0 -0
- package/templates/basic/public/images/test/3.jpg +0 -0
- package/templates/basic/public/images/test/4.jpg +0 -0
- package/templates/basic/public/images/test/5.jpg +0 -0
- package/templates/basic/scripts/start.js +3 -0
- package/templates/basic/src/Routers.tsx +40 -0
- package/templates/basic/src/client/index.tsx +37 -0
- package/templates/basic/src/component/Header.tsx +38 -0
- package/templates/basic/src/component/Layout.tsx +24 -0
- package/templates/basic/src/component/Loading.tsx +7 -0
- package/templates/basic/src/component/Theme.tsx +14 -0
- package/templates/basic/src/containers/Home.tsx +435 -0
- package/templates/basic/src/containers/Login.tsx +32 -0
- package/templates/basic/src/containers/Photo.tsx +162 -0
- package/templates/basic/src/css/test.css +13 -0
- package/templates/basic/src/css/test.less +8 -0
- package/templates/basic/src/css/test2.sass +7 -0
- package/templates/basic/src/css/test3.scss +8 -0
- package/templates/basic/src/externals/less.d.ts +4 -0
- package/templates/basic/src/externals/window.d.ts +3 -0
- package/templates/basic/src/reducers/home.ts +17 -0
- package/templates/basic/src/reducers/index.ts +26 -0
- package/templates/basic/src/reducers/photo.ts +23 -0
- package/templates/basic/src/server/index.ts +29 -0
- package/templates/basic/src/server/photo.ts +118 -0
- package/templates/basic/src/server/utils.tsx +158 -0
- package/templates/basic/src/services/home.ts +52 -0
- package/templates/basic/src/services/photo.ts +64 -0
- package/templates/basic/src/store/constants.ts +4 -0
- package/templates/basic/src/store/index.ts +14 -0
- package/templates/basic/src/styled/common.ts +26 -0
- package/templates/basic/src/styled/component/header.ts +166 -0
- package/templates/basic/src/styled/component/layout.ts +10 -0
- package/templates/basic/src/styled/home.ts +789 -0
- package/templates/basic/src/styled/photo.ts +44 -0
- package/templates/basic/src/styled/test.ts +14 -0
- package/templates/basic/src/utils/clientConfig.ts +2 -0
- package/templates/basic/src/utils/config.ts +7 -0
- package/templates/basic/src/utils/fetch.ts +26 -0
- package/templates/basic/src/utils/index.ts +45 -0
- package/templates/basic/tsconfig.json +18 -0
- package/templates/basic/webpack.base.js +262 -0
- package/templates/basic/webpack.client.js +26 -0
- package/templates/basic/webpack.server.js +33 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import styled from 'styled-components'
|
|
2
|
+
|
|
3
|
+
export const Container = styled.div`
|
|
4
|
+
display: flex;
|
|
5
|
+
flex: 1;
|
|
6
|
+
flex-direction: column;
|
|
7
|
+
justify-content: flex-start;
|
|
8
|
+
align-items: flex-start;
|
|
9
|
+
margin: 20px;
|
|
10
|
+
|
|
11
|
+
.demo4 {
|
|
12
|
+
display: flex;
|
|
13
|
+
align-items: center;
|
|
14
|
+
height: 700px;
|
|
15
|
+
position: relative;
|
|
16
|
+
|
|
17
|
+
.demo4-inner {
|
|
18
|
+
overflow: hidden;
|
|
19
|
+
position: relative;
|
|
20
|
+
margin: auto;
|
|
21
|
+
|
|
22
|
+
.demo4-photo {
|
|
23
|
+
position: absolute;
|
|
24
|
+
background-color: lightgray;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
`
|
|
29
|
+
|
|
30
|
+
export const Row = styled.div`
|
|
31
|
+
display: flex;
|
|
32
|
+
flex-direction: row;
|
|
33
|
+
justify-content: flex-start;
|
|
34
|
+
align-items: center;
|
|
35
|
+
font-size: 20px;
|
|
36
|
+
word-wrap: break-word;
|
|
37
|
+
word-break: break-all;
|
|
38
|
+
overflow: hidden;
|
|
39
|
+
padding-bottom: 10px;
|
|
40
|
+
|
|
41
|
+
a {
|
|
42
|
+
padding-right: 10px;
|
|
43
|
+
}
|
|
44
|
+
`
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import axios from 'axios'
|
|
2
|
+
|
|
3
|
+
let prefix = 'http://localhost:3001'
|
|
4
|
+
|
|
5
|
+
export const doGet = (action:any) => {
|
|
6
|
+
return new Promise((resolve, reject) => {
|
|
7
|
+
|
|
8
|
+
if(typeof window !== "undefined"){
|
|
9
|
+
prefix = window.location.origin
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
let url = action
|
|
13
|
+
if (action.indexOf('http') === -1) {
|
|
14
|
+
if (action.substring(0, 1) !== '/') {
|
|
15
|
+
url = prefix + '/' + action
|
|
16
|
+
} else {
|
|
17
|
+
url = prefix + action
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
axios
|
|
22
|
+
.get(url)
|
|
23
|
+
.then(resolve)
|
|
24
|
+
.catch(reject)
|
|
25
|
+
})
|
|
26
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export const getLocationParams = (param: any) => {
|
|
2
|
+
let result = ''
|
|
3
|
+
if (param !== '') {
|
|
4
|
+
const href = window?.location?.href
|
|
5
|
+
if (href && href.indexOf('?') !== -1) {
|
|
6
|
+
const query = href.split('?')[1]
|
|
7
|
+
const queryArr = query.split('&')
|
|
8
|
+
|
|
9
|
+
queryArr.forEach((item) => {
|
|
10
|
+
const itemArr = item.split('=')
|
|
11
|
+
|
|
12
|
+
if (param.toLowerCase() === itemArr[0].toLowerCase()) {
|
|
13
|
+
result = itemArr[1]
|
|
14
|
+
return false
|
|
15
|
+
}
|
|
16
|
+
})
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return result
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const isSEO = () => {
|
|
23
|
+
if (typeof window !== 'undefined') {
|
|
24
|
+
let seo: any = getLocationParams('seo')
|
|
25
|
+
if (seo !== '') {
|
|
26
|
+
seo = parseInt(seo, 10)
|
|
27
|
+
}
|
|
28
|
+
return seo
|
|
29
|
+
}
|
|
30
|
+
return 0
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const handleLink = (link: string) => {
|
|
34
|
+
let result = link
|
|
35
|
+
|
|
36
|
+
if (isSEO()) {
|
|
37
|
+
if (link.indexOf('?') !== -1) {
|
|
38
|
+
result += '&'
|
|
39
|
+
} else {
|
|
40
|
+
result += '?'
|
|
41
|
+
}
|
|
42
|
+
result += 'seo=1'
|
|
43
|
+
}
|
|
44
|
+
return result
|
|
45
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "esnext", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
|
|
4
|
+
"lib": ["es5", "es6", "dom"], /* Specify library files to be included in the compilation. */ "module": "esnext", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
|
|
5
|
+
"removeComments": false, /* Do not emit comments to output. @loadable/components 必须置为 false */
|
|
6
|
+
"jsx": "react", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
|
|
7
|
+
"sourceMap": true, /* Generates corresponding '.map' file. */
|
|
8
|
+
"outDir": "./build/", /* Redirect output structure to the directory. */
|
|
9
|
+
"noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
|
10
|
+
"allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
|
|
11
|
+
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
|
|
12
|
+
"preserveConstEnums": true
|
|
13
|
+
},
|
|
14
|
+
"include":[
|
|
15
|
+
"./src/**/*",
|
|
16
|
+
"./src/externals/*.d.ts"
|
|
17
|
+
]
|
|
18
|
+
}
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
const path = require('path')
|
|
2
|
+
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
|
|
3
|
+
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
|
|
4
|
+
const TerserPlugin = require('terser-webpack-plugin')
|
|
5
|
+
const { version } = require('./package.json')
|
|
6
|
+
const LoadablePlugin = require('@loadable/webpack-plugin')
|
|
7
|
+
const { createLoadableComponentsTransformer } = require('typescript-loadable-components-plugin')
|
|
8
|
+
const BrowserSyncPlugin = require('browser-sync-webpack-plugin')
|
|
9
|
+
|
|
10
|
+
// const createStyledComponentsTransformer =
|
|
11
|
+
// require('typescript-plugin-styled-components').default
|
|
12
|
+
// const styledComponentsTransformer = createStyledComponentsTransformer()
|
|
13
|
+
|
|
14
|
+
module.exports = ({ mode, entry, server, init }) => {
|
|
15
|
+
const config = {
|
|
16
|
+
mode,
|
|
17
|
+
entry,
|
|
18
|
+
devtool: 'source-map',
|
|
19
|
+
resolve: {
|
|
20
|
+
extensions: ['.ts', '.tsx', '.js', '.jsx', '.json']
|
|
21
|
+
},
|
|
22
|
+
module: {
|
|
23
|
+
rules: [
|
|
24
|
+
{
|
|
25
|
+
test: /\.(ts|js)x?$/,
|
|
26
|
+
exclude: /node_modules/,
|
|
27
|
+
use: [
|
|
28
|
+
{
|
|
29
|
+
loader: 'babel-loader',
|
|
30
|
+
options: {
|
|
31
|
+
presets: [
|
|
32
|
+
'@babel/preset-react',
|
|
33
|
+
[
|
|
34
|
+
'@babel/preset-env',
|
|
35
|
+
{
|
|
36
|
+
targets: {
|
|
37
|
+
browsers: ['last 2 versions'] //对主流浏览器最近两个版本进行兼容
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
],
|
|
42
|
+
plugins: [
|
|
43
|
+
['@babel/plugin-transform-class-properties'],
|
|
44
|
+
['@babel/plugin-transform-optional-chaining'],
|
|
45
|
+
["@babel/plugin-syntax-dynamic-import"],
|
|
46
|
+
['babel-plugin-styled-components'],
|
|
47
|
+
["@loadable/babel-plugin"]
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
loader: 'ts-loader',
|
|
53
|
+
options: {
|
|
54
|
+
logInfoToStdOut: true,
|
|
55
|
+
logLevel: 'info',
|
|
56
|
+
transpileOnly: true,
|
|
57
|
+
configFile: path.resolve(__dirname, './tsconfig.json'),
|
|
58
|
+
getCustomTransformers: (program) => {
|
|
59
|
+
// console.log('getCustomTransformers', program)
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
before: [
|
|
63
|
+
//createLoadableComponentsTransformer(program, {}),
|
|
64
|
+
// styledComponentsTransformer,
|
|
65
|
+
createLoadableComponentsTransformer(program, {
|
|
66
|
+
setComponentId: true,
|
|
67
|
+
setDisplayName: true,
|
|
68
|
+
minify: true,
|
|
69
|
+
}),
|
|
70
|
+
//loadableTransformer
|
|
71
|
+
]
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
]
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
test: /\.less$/,
|
|
80
|
+
use: [
|
|
81
|
+
mode === 'production' || server
|
|
82
|
+
? MiniCssExtractPlugin.loader
|
|
83
|
+
: 'style-loader',
|
|
84
|
+
{
|
|
85
|
+
loader: 'css-loader',
|
|
86
|
+
options: {
|
|
87
|
+
importLoaders: 1,
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
'postcss-loader',
|
|
91
|
+
{
|
|
92
|
+
loader: 'less-loader',
|
|
93
|
+
options: {
|
|
94
|
+
lessOptions: {
|
|
95
|
+
javascriptEnabled: true,
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
]
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
test: /\.s(a|c)ss$/,
|
|
103
|
+
use: [
|
|
104
|
+
mode === 'production' || server
|
|
105
|
+
? MiniCssExtractPlugin.loader
|
|
106
|
+
: 'style-loader',
|
|
107
|
+
{
|
|
108
|
+
loader: 'css-loader',
|
|
109
|
+
options: {
|
|
110
|
+
importLoaders: 1,
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
'postcss-loader',
|
|
114
|
+
'sass-loader'
|
|
115
|
+
]
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
test: /\.css$/,
|
|
119
|
+
use: [
|
|
120
|
+
mode === 'production' || server
|
|
121
|
+
? MiniCssExtractPlugin.loader
|
|
122
|
+
: 'style-loader',
|
|
123
|
+
{
|
|
124
|
+
loader: 'css-loader',
|
|
125
|
+
options: {
|
|
126
|
+
importLoaders: 1,
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
'postcss-loader'
|
|
130
|
+
]
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
test: /\.(png|svg|jp?g|webp|gif)$/i,
|
|
134
|
+
type: 'asset/resource'
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
test: /\.(woff|woff2|eot|ttf|otf)$/,
|
|
138
|
+
type: 'asset/resource',
|
|
139
|
+
generator: {
|
|
140
|
+
filename: 'fonts/[name][ext]'
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
]
|
|
144
|
+
},
|
|
145
|
+
plugins: [
|
|
146
|
+
new LoadablePlugin({
|
|
147
|
+
writeToDisk: true
|
|
148
|
+
})
|
|
149
|
+
],
|
|
150
|
+
optimization: {
|
|
151
|
+
minimize: mode === 'production' || server ? true : false,
|
|
152
|
+
minimizer: [`...`, new CssMinimizerPlugin()]
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if(init){
|
|
157
|
+
config.cache = false
|
|
158
|
+
} else {
|
|
159
|
+
config.cache = {
|
|
160
|
+
type: 'filesystem',
|
|
161
|
+
cacheDirectory: path.resolve(__dirname, '.temp_cache'),
|
|
162
|
+
// type: 'memory',
|
|
163
|
+
// cacheUnaffected: true,
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if(mode === 'development' && !server){
|
|
168
|
+
config.plugins.push(
|
|
169
|
+
new BrowserSyncPlugin(
|
|
170
|
+
{
|
|
171
|
+
host: 'localhost',
|
|
172
|
+
port: 3000,
|
|
173
|
+
proxy: 'http://localhost:3001/'
|
|
174
|
+
}
|
|
175
|
+
)
|
|
176
|
+
)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if(mode === 'production' || server){
|
|
180
|
+
config.plugins.push(
|
|
181
|
+
new MiniCssExtractPlugin({
|
|
182
|
+
filename: `css/[name].${version}.css`
|
|
183
|
+
})
|
|
184
|
+
)
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (!server) {
|
|
188
|
+
if (mode === 'development') {
|
|
189
|
+
config.entry['vendor'] = ['react', 'react-dom']
|
|
190
|
+
} else if (mode === 'production') {
|
|
191
|
+
config.optimization.minimizer.push(
|
|
192
|
+
new TerserPlugin({
|
|
193
|
+
terserOptions: {
|
|
194
|
+
compress: {
|
|
195
|
+
drop_debugger: true,
|
|
196
|
+
//drop_console: true,
|
|
197
|
+
pure_funcs: ['console.log']
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
})
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
config.optimization['splitChunks'] = {
|
|
204
|
+
chunks: 'all',
|
|
205
|
+
minSize: 20000,
|
|
206
|
+
minRemainingSize: 0,
|
|
207
|
+
minChunks: 1,
|
|
208
|
+
maxAsyncRequests: 30,
|
|
209
|
+
maxInitialRequests: 30,
|
|
210
|
+
enforceSizeThreshold: 50000,
|
|
211
|
+
name: false,
|
|
212
|
+
cacheGroups: {
|
|
213
|
+
framework: {
|
|
214
|
+
// 将react和react-dom打入framework当中
|
|
215
|
+
name: 'framework',
|
|
216
|
+
test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/, //匹配库当中的react和react-dom
|
|
217
|
+
priority: 40, //权重为40 最大权重
|
|
218
|
+
reuseExistingChunk: true
|
|
219
|
+
},
|
|
220
|
+
lib: {
|
|
221
|
+
test: (module) => {
|
|
222
|
+
// 匹配包大于160000的
|
|
223
|
+
if (module.size() > 20000) {
|
|
224
|
+
console.log('test_module', module.identifier(), module.size())
|
|
225
|
+
}
|
|
226
|
+
return module.size() > 20000
|
|
227
|
+
},
|
|
228
|
+
name(module) {
|
|
229
|
+
//名字就是包当中的名字
|
|
230
|
+
return (
|
|
231
|
+
/[\\/]node_modules[\\/](.*)/.exec(module.identifier()) &&
|
|
232
|
+
/[\\/]node_modules[\\/](.*)/.exec(module.identifier()).length &&
|
|
233
|
+
/[\\/]node_modules[\\/](.*)/.exec(module.identifier())[1].replace(/\/|\\/g, '_')
|
|
234
|
+
)
|
|
235
|
+
},
|
|
236
|
+
minChunks: 1, //最小共用次数为1时就使用
|
|
237
|
+
priority: 30, //权重为30
|
|
238
|
+
reuseExistingChunk: true
|
|
239
|
+
},
|
|
240
|
+
vendor: {
|
|
241
|
+
name: 'vendor',
|
|
242
|
+
test: /[\\/]node_modules[\\/]/,
|
|
243
|
+
priority: 20,
|
|
244
|
+
reuseExistingChunk: true
|
|
245
|
+
},
|
|
246
|
+
default: {
|
|
247
|
+
name: 'default',
|
|
248
|
+
minChunks: 2,
|
|
249
|
+
priority: 10,
|
|
250
|
+
reuseExistingChunk: true
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
config.optimization['runtimeChunk'] = {
|
|
256
|
+
name: 'runtime'
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return config
|
|
262
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const path = require('path') //node的path模块
|
|
2
|
+
const { merge } = require('webpack-merge')
|
|
3
|
+
const config = require('./webpack.base.js')
|
|
4
|
+
const { version } = require('./package.json')
|
|
5
|
+
|
|
6
|
+
const server = false
|
|
7
|
+
|
|
8
|
+
const entry = {
|
|
9
|
+
client: ['./src/client/index.tsx']
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const clientConfig = {
|
|
13
|
+
output: {
|
|
14
|
+
//打包出口
|
|
15
|
+
path: path.resolve(__dirname, 'public'),
|
|
16
|
+
filename: ({ chunk }) => {
|
|
17
|
+
const { name } = chunk
|
|
18
|
+
// console.log('name', name)
|
|
19
|
+
return `js/[name].${version}.bundle.js`
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
module.exports = (_, { mode }) => {
|
|
25
|
+
return merge(config({ mode, entry, server }), clientConfig)
|
|
26
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const path = require('path') //node的path模块
|
|
2
|
+
const nodeExternals = require('webpack-node-externals')
|
|
3
|
+
const { merge } = require('webpack-merge')
|
|
4
|
+
const config = require('./webpack.base.js')
|
|
5
|
+
const { version } = require('./package.json')
|
|
6
|
+
|
|
7
|
+
const init = process.env.INIT || 0
|
|
8
|
+
const server = true
|
|
9
|
+
|
|
10
|
+
console.log('init', init)
|
|
11
|
+
|
|
12
|
+
const entry = {
|
|
13
|
+
server: ['./src/server/index.ts']
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const serverConfig = {
|
|
17
|
+
target: 'node',
|
|
18
|
+
output: {
|
|
19
|
+
//打包出口
|
|
20
|
+
filename: `bundle.${version}.js`, //打包后的文件名
|
|
21
|
+
path: path.resolve(__dirname, 'build'), //存放到根目录的build文件夹
|
|
22
|
+
clean: true,
|
|
23
|
+
libraryTarget: 'commonjs2'
|
|
24
|
+
},
|
|
25
|
+
externals: [
|
|
26
|
+
'@loadable/component',
|
|
27
|
+
nodeExternals()
|
|
28
|
+
] //保持node中require的引用方式
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
module.exports = (_, { mode }) => {
|
|
32
|
+
return merge(config({ mode, entry, server, init }), serverConfig)
|
|
33
|
+
}
|