打包多页应用
entry: { // 多入口
home: './src/index.js',
other: './src/other.js',
},
output: { // 多出口: 通过[name]实现多出口
filename: '[name].js',
path: path.resolve(__dirname, 'build'),
},
plugins: [ // 通过chunks指定html引入的js文件,否则会引入所有的js文件
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'home.html',
chunks: ['home']
}),
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'other.html',
chunks: ['other']
}),
],
source-map
打包时,开发环境源代码经过压缩、去空格、babel编译转化,最终得到适用于生产环境的项目代码,这样处理后的项目代码和源代码之间差异性很大。假如生产环境中的代码出现bug,调试的时只能定位到压缩处理后的代码位置,却无法定位到源代码。source-map构建了源代码和生产环境项目代码之间的桥梁,解决了上述代码的定位问题。
webapck中常见的source-map类型
eval: 不生成sourcemap文件,仅在每一个模块后,增加sourceURL来关联模块处理前后的对应关系。优点: 打包速度快 cheap: 忽略原始代码中的列信息,且没有loader之间的的sourcemap信息,但生成单独的sourcemap文件 module: 包含loader之间的sourcemap信息
- source-map: 生成单独的sourcemap文件,出错后会标识出错的行和列
- eval-source-map: 不会产生单独的映射文件,但是会显示行和列
- cheap-module-source-map: 产生单独的映射文件,不产生列。一般用于调试,相对于source-map,打包后的文件更小
- cheap-module-eval-source-map: 不产生单独的映射文件,不产生列,集成在打包后的文件中。开发环境推荐使用
devtool: 'source-map'
实时打包
watch: true, // 可以监听文件变化,如果修改后会重新编译
watchOptions: {
poll: 1000, // 轮询时间
aggregateTimeout: 500, // 防抖
ignored: /node_modules/, // 忽略的文件
},
解决跨域问题
原理: 服务器端向服务器端发送请求时不存在跨域
devServer-proxy直接代理
devServer: {
proxy: {
'/api': 'http://localhost:3000',
}
}
devServer-proxy pathRewrite方式
devServer: {
proxy: {
'/api': { // 捕获API的标志,如果API中有这个字符串,那么就开始匹配代理
target: 'http://www.baidu.com/', // 需要跨域的API地址,如果是域名需要额外添加一个参数changeOrigin: true,否则会代理失败。
changeOrigin: true,
pathRewrite: {'^/api' : ''}, // 路径重写。比如访问的API路径:/api/users, 最终代理访问路径:http://www.baidu.com/users,
secure: false, // 设置支持https协议的代理
},
}
}
单纯mock数据
利用webpack-dev-server内部的express实现。
devServer: {
before(app) { // 此处的app就是express中的app,通过app编写接口。
app.get('/user', (req, res) => {
res.json({ color: 'red'});
});
}
}
server+webpack,使服务端和客户端启动在同一个端口
webpack-dev-middleware: 生成一个与webpack的compiler绑定的中间件,在express启动的app中调用这个中间件。 这个中间件的作用:
- 通过watch mode,监听资源的变更,然后自动打包;
- 快速编译,走内存;
- 返回中间件,支持express的use格式
- 使用:
let webpack = require('webpack');
let middle = require('webpack-dev-middleware');// webpack开发服务中间件
let config = require('./webpack.config.js');
let compiler = webpack(config);
app.use(middle(compiler));
app.get('/user', (req, res) => {
res.json({ color: 'red'});
});
app.listen(3000);
在启动服务端时,连带着启动webpackDevServer,并且在同一端口上
resolve解析
resolve: {
modules: [path.resolve('node_modules')], // 解析范围
alias:{ // 指定别名和对应的文件
'bootstrap': 'bootstrap/dist/css/bootstrap.css'
},
// mainFields: ['style', 'main'], // 查找入口字段(package.json),先查找style 再查找main(默认为main)
extensions: ['.js', '.css', '.json'], // 扩展名:解析文件的默认后缀名
}
定义环境变量
plugins: [
new webpack.DefinePlugin({
DEV: JSON.stringify('dev'), // 给字符串添加双引号 因为定义的值在执行时会去掉包裹的单引号
FALG: 'true',
}),
]
// js中的使用
let url = ''
if(DEV === 'dev') {
url = 'http://localhost:3000';
) else {
url = 'http://www.baidu.com'
}
console.log(typeof FLAG); // boolean
如果定义的环境变量是一个字符串,需通过JSON.stringify进行转化。因为,如果使用'',定义的环境环境变量被当做一个变量
webpack配置文件合并: webpack-merge
生产环境和开发环境配置不同,项目中需要在不同的文件中分别进行webpack配置.一般将公用配置放在webpack.base.config.js,开发环境特殊配置放在webpack.dev.config.js,生产环境特殊配置放在webpack.prod.config.js,通过webpack-merge合并公用配置和指定环境特殊配置
// webpack.prov.config.js
let {smart} = require('webpack-merge');
let base = require('./webpack.base.js');
module.exports = smart(base, {
mode: 'production',
optimization: {
minimizer: []
},
plugins: []
});
// webpack.dev.config.js
let {smart} = require('webpack-merge');
let base = require('./webpack.base.js');
module.exports = smart(base, {
mode: 'development',
devServer: {
},
devtool: 'source-map',
});