create-react-app 配置多页面

最近遇到一个需求,开发chrome插件的时候存在多个html页面,create-react-app 脚手架默认是单html开发的,所以需要重新配置一下wepack,实现多个页面输入和输出。

实例说明

项目地址

完成后的目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
.
├── LICENSE
├── README.md
├── build
│ ├── asset-manifest.json
│ ├── favicon.ico
│ ├── houser.jpg
│ ├── index.html
│ ├── location.png
│ ├── popup.html
│ ├── service-worker.js
│ └── static
│ ├── css
│ │ ├── index.773fa05a.css
│ │ └── index.773fa05a.css.map
│ └── js
│ ├── index.98348617.js
│ ├── index.98348617.js.map
│ ├── popup.7ae02277.js
│ └── popup.7ae02277.js.map
├── build.zip
├── config
│ ├── env.js
│ ├── jest
│ │ ├── cssTransform.js
│ │ └── fileTransform.js
│ ├── paths.js
│ ├── polyfills.js
│ ├── webpack.config.dev.js
│ ├── webpack.config.prod.js
│ └── webpackDevServer.config.js
├── package-lock.json
├── package.json
├── public
│ ├── background
│ │ ├── 139.jpg
│ │ └── 444H.jpg
│ ├── favicon.ico
│ ├── houser.jpg
│ ├── index.html
│ └── location.png
├── scripts
│ ├── build.js
│ ├── start.js
│ └── test.js
└── src
├── index
│ ├── App.js
│ ├── App.less
│ ├── App.test.js
│ ├── components
│ ├── config.js
│ ├── index.js
│ ├── index.less
│ ├── logo.svg
│ ├── page
│ ├── registerServiceWorker.js
│ ├── service
│ ├── stores
│ └── utils
└── popup
├── App.js
├── App.less
├── components
├── index.js
└── registerServiceWorker.js

目录说明: 多个页面在分文件夹单独放置在src下,分别为index和popup,build之后都在一个文件里。为了缩短篇幅,删除一些无用目录。

流程

暴露出create-react-app的配置文件

1
$ create-react-app eject

修改path

找到config目录下的paths.js,添加需要的路径变量,后续引用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
module.exports = {
dotenv: resolveApp('.env'),
appBuild: resolveApp('build'),
appPublic: resolveApp('public'),
appHtml: resolveApp('public/index.html'),
appIndexJs: resolveApp('src/index/index.js'), //此处是默认页面入口js路径
appPopupJs: resolveApp('src/popup/index.js'), //自行添加的popup.html页面的入口js路径
appPackageJson: resolveApp('package.json'),
appSrc: resolveApp('src'),
yarnLockFile: resolveApp('yarn.lock'),
testsSetup: resolveApp('src/setupTests.js'),
appNodeModules: resolveApp('node_modules'),
publicUrl: getPublicUrl(resolveApp('package.json')),
servedPath: getServedPath(resolveApp('package.json')),
};

修改webpack.config.dev.js

修改webpack.config.dev.js

entry增加入口文件

1
2
3
4
5
6
7
8
9
10
11
12
entry: {
index: [
require.resolve('./polyfills'),
require.resolve('react-dev-utils/webpackHotDevClient'),
paths.appIndexJs,
],
popup: [
require.resolve('./polyfills'),
require.resolve('react-dev-utils/webpackHotDevClient'),
paths.appPopupJs, // paths.js中配置的路径,也可以写成 paths.appSrc + '/popup/index.js',
]
},

修改output输出文件名,避免冲突

1
2
3
4
5
6
7
8
output: {
pathinfo: true,
filename: 'static/js/[name].bundle.js', // 添加 [name]
chunkFilename: 'static/js/[name].chunk.js',
publicPath: publicPath,
devtoolModuleFilenameTemplate: info =>
path.resolve(info.absoluteResourcePath).replace(/\\/g, '/'),
},

增加并修改 HtmlWebpackPlugin 插件配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
plugins: [
// ...
new HtmlWebpackPlugin({
inject: true,
chunks: ["index"], // 指定入口 js 文件
filename: 'index.html', //配置输入文件名
template: paths.appHtml,
}),
new HtmlWebpackPlugin({
inject: true,
chunks: ["popup"], // 指定入口 js 文件
filename: 'popup.html', //配置输入文件名
template: paths.appHtml,
}),
// ...
],

修改webpack.config.prod.js

webpack.config.prod.js 修改方式跟 webpack.config.dev.js基本一样,只需要配置入口,出口和html插件,其他配置不要改变。

结语

webpack的基本流程就是入口和出口,中间经过loader和插件进行处理,所以多页面的配置只需要针对入口和出口进行增加配置即可。例如build的时候也可以进行分文件导出,只需要调整一下文件生成路径就行。