解决的问题
1:多页面结构如何设置,2:公共样式如何配置,3:入口文件都需要导入哪些样式 ,4:如何自动配置入口文件而不需要手动书写。
首先看下项目目录
该项目有两个页面,分别位于index和login文件夹下,
common.css为公共样式
实现的主要功能:
1:通过AutoWebPlugin提取公共代码
2:通过AutoWebPlugin自动设置入口文件,再新添加文件也不用再写入口文件。
3:多个页面共用一个模板
4:通过AutoWebPlugin配置页面所需的公共文件
webpack.config.js文件
const path = require('path');
const UglifyJsPlugin = require('webpack/lib/optimize/UglifyJsPlugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const DefinePlugin = require('webpack/lib/DefinePlugin');
const { AutoWebPlugin } = require('web-webpack-plugin');
// 使用本文的主角 AutoWebPlugin,自动寻找 pages 目录下的所有目录,把每一个目录看成一个单页应用
const autoWebPlugin = new AutoWebPlugin('pages', {
template: './template.html', // HTML 模版文件所在的文件路径
postEntrys: ['./common.css'],// 所有页面都依赖这份通用的 CSS 样式文件
// 提取出所有页面公共的代码
commonsChunk: {
name: 'common',// 提取出公共代码 Chunk 的名称
},
});
module.exports = {
// AutoWebPlugin 寻找到的所有单页应用,生成对应的入口配置,
// autoWebPlugin.entry 方法可以获取到生成入口配置
// 这里就相当于entry: {
// "index": ['./pages/index/index.js','./common.css'], 由此可以看出chunk就是文件夹的名字
// "login": ['./pages/login/index.js','./common.css']
// }
entry: autoWebPlugin.entry({
// 这里可以加入你额外需要的 Chunk 入口
}),
output: {
filename: '[name]_[chunkhash:8].js',// 给输出的文件名称加上 hash 值
path: path.resolve(__dirname, './dist'),
},
module: {
rules: [
{
test: /\.js$/,
use: ['babel-loader'],
// 排除 node_modules 目录下的文件,node_modules 目录下的文件都是采用的 ES5 语法,没必要再通过 Babel 去转换
exclude: path.resolve(__dirname, 'node_modules'),
},
{
test: /\.css/,// 增加对 CSS 文件的支持
// 提取出 Chunk 中的 CSS 代码到单独的文件中
use: ExtractTextPlugin.extract({
use: ['css-loader?minimize'] // 压缩 CSS 代码
}),
},
]
},
plugins: [
autoWebPlugin,
new ExtractTextPlugin({
filename: `[name]_[contenthash:8].css`,// 给输出的 CSS 文件名称加上 hash 值
}),
new DefinePlugin({
// 定义 NODE_ENV 环境变量为 production 去除 react 代码中的开发时才需要的部分
'process.env': {
NODE_ENV: JSON.stringify('production')
}
}),
// 压缩输出的 JS 代码
new UglifyJsPlugin({
// 最紧凑的输出
beautify: false,
// 删除所有的注释
comments: false,
compress: {
// 在UglifyJs删除没有用到的代码时不输出警告
warnings: false,
// 删除所有的 `console` 语句,可以兼容ie浏览器
drop_console: true,
// 内嵌定义了但是只用到一次的变量
collapse_vars: true,
// 提取出出现多次但是没有定义成变量去引用的静态值
reduce_vars: true,
}
}),
],
};
再看一下index.js入口文件
import React, { Component } from 'react';
import { render } from 'react-dom';
//只需导入自己所需样式,公共样式通过autoWebPlugin配置,不需导入
import './index.css';
class App extends Component {
render() {
return <h1>Page Index</h1>
}
}
render(<App/>, window.document.getElementById('app'));
最后看下模板
<html>
<head>
<meta charset="UTF-8">
<!--该页面所依赖的其它剩下的 CSS 注入的地方-->
<!--STYLE-->
<!--注入 google_analytics 中的 JS 代码-->
<script src="./google_analytics.js?_inline"></script>
<!--异步加载 Disqus 评论-->
<script src="https://dive-into-webpack.disqus.com/embed.js" async></script>
</head>
<body>
<div id="app"></div>
<!--该页面所依赖的其它剩下的 JavaScript 注入的地方-->
<!--SCRIPT-->
<!--Disqus 评论容器-->
<div id="disqus_thread"></div>
</body>
</html>
因为模板是共用的的所以,不能向单页面指定css和js的文件名了,因为不同入口文件,生成的名称都不一样,所以这里用 style 和 javascript 标记需导入的位置即可。