一、管理文件输出
项目结构:
webpack-test
|- package.json
|- webpack.config.js
|- dist
|- index.html
|- src
|- index1.js
|- index2.js
|- node_modules
index1.js
export default function() {
console.log('this is index1.js!');
}
index2.js
export default function() {
console.log('this is index2.js!');
}
index.html
<!doctype html>
<html>
<head>
<title>Webpack Test</title>
</head>
<body>
<script src="./a.bundle.js"></script>
<script src="./b.bundle.js"></script>
</body>
</html>
webpack.config.js
const path = require('path');
module.exports = {
entry: {
a: './src/index1.js',
b: './src/index2.js'
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
}
npm script中添加脚本命令:
"scripts": {
"build": "webpack",
}
使用HtmlWebpackPlugin
运行命令,就会发现dist目录下生成了a.bundle.js和b.bundle.js。但如果,更改配置中的入口文件的名称,相应的index.html也要修改,这就会很麻烦。HtmlWebpackPlugin插件在构建时每次都创建一个index.html替代之前的index.html,新创建的html文件中包含使用script标签的body中的所有webpack包。这对bundle名称在每次编译之后都变化(如以哈希值命名)的情况下很有效。
安装
npm install --save-dev html-webpack-plugin
修改webpack.config.js
const path = require('path');
+ const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
- a: './src/index1.js',
- b: './src/index2.js'
+ 1: './src/index1.js',
+ 2: './src/index2.js'
},
+ plugins: [
+ new HtmlWebpackPlugin({
+ title: 'Webpack Test' // 生成的html文件的标题
+ })
+ ],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
运行 npm run build
,就会发现HtmlWebpackPlugin创建了一个新的index.html,而且包含新的bundle。
使用ExtractTextWebpackPlugin
ExtractTextWebpackPlugin插件会将所有入口chunk中的.css文件移动到独立分离的 CSS 文件,并插入到index.html文件的 <link>
标签中。它可以跟js bundle并行加载。
安装
npm install --save-dev extract-text-webpack-plugin
在src目录下添加index1.css和index2.css:
.index1: {
color: red;
}
.index2: {
color: red;
}
然后在index1.js和index2.js里分别引入css文件:
index1.js:
import './index1.css';
index2.js:
import './index2.css';
修改webpack.config.js:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
+ const ExtractTextPlugin= require('extract-text-webpack-plugin');
module.exports = {
entry: {
1: './src/index1.js',
2: './src/index2.js'
},
plugins: [
+ new ExtractTextPlugin('[name].css'), // 每个入口 chunk 都生成一个对应的文件
new HtmlWebpackPlugin({
title: 'Webpack Test'
})
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
},
+ module: {
+ rules: [{
+ test: /\.css$/,
+ use: ExtractTextPlugin.extract({
+ fallback: 'style-loader', // 应用于当css没有被提取的时候
+ use: 'css-loader' // 用于将css文件转换成一个导出模块
+ })
+ }]
+ }
};
运行 npm run build
,就会发现index.html中新增了两个 <link>
标签。
使用CleanWebpackPlugin
如果修改入口文件名称再进行构建,则会导致dist目录下遗留上一次的bundle文件等。所以dist目录下多出了很多不必要的文件,应该先清理掉。
安装
npm install clean-webpack-plugin --save-dev
修改webpack.config.js:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin= require('extract-text-webpack-plugin');
+ const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
entry: {
1: './src/index1.js',
2: './src/index2.js'
},
plugins: [
+ new CleanWebpackPlugin(['dist']), //清空dist目录
new ExtractTextPlugin('[name].css'), // 每个入口 chunk 都生成一个对应的文件
new HtmlWebpackPlugin({
title: 'Webpack Test'
})
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader', // 应用于当css没有被提取的时候
use: 'css-loader' // 用于将css文件转换成一个导出模块
})
}]
}
};
运行 npm run build
,就会发现dist目录下只剩下新构建的文件。
二、自动构建
每次修改项目文件之后,都要运行 npm run build
命令去重新构建十分繁琐。而webpack提供了三种方案在修改文件之后进行自动构建:
- 观察模式(Watch Mode)
- webpack-dev-server (多数)
- webpack-dev-middleware
1. 观察模式
在 npm script 脚本中添加命令:
"watch": "webpack --watch",
然后运行 npm run watch
,会看到Webpack is watching the files…且命令行不会退出,srcipt脚本仍然在观察文件。使用观察模式需要手动刷新浏览器才能看到修改后的效果。
2. webpack-dev-server
webpack-dev-server提供了简单的web服务器,并实时重新加载。
安装 webpack-dev-server
npm install --save-dev webpack-dev-server
修改webpack.config.js,添加devServer配置:
const path = require('path');
module.exports = {
...
devServer: {
contentBase: 'some/path', // 可访问文件的路径,告诉服务器从哪里提供内容
port: 9000 // 端口号
}
...
}
在npm script脚本中添加命令:
"start": "webpack-dev-server --open", // open参数可以让服务器在启动时打开浏览器
运行 npm run start
命令,就会看到浏览器自动跳转到http://localhost:9000/,修改源文件会让浏览器重新刷新。
3. webpack-dev-middleware
webpack-dev-middleware是一个与webpack的compiler绑定的中间件,可以在express服务中使用。
它通过watch mode以实现对变更文件的监控,然后自动打包编译进内存中,减少打包进本地磁盘的时间。webpack-dev-server在内部使用了它。
安装
npm install --save-dev express webpack-dev-middleware
修改webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin= require('extract-text-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
entry: {
1: './src/index1.js',
2: './src/index2.js'
},
plugins: [
new CleanWebpackPlugin(),
new ExtractTextPlugin('[name].css'), // 每个入口 chunk 都生成一个对应的文件
new HtmlWebpackPlugin({
title: 'Webpack Test'
})
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
+ publicPath: '/'
},
module: {
rules: [{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: 'css-loader'
})
}]
}
};
设置自定义的 express 服务:
webpack-test
|- package.json
|- webpack.config.js
+ |- server.js
|- dist
|- index.html
|- src
|- index1.js
|- index2.js
|- node_modules
server.js
const express = require('express');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
const app = express();
const config = require('./webpack.config.js');
const compiler = webpack(config);
app.use(webpackDevMiddleware(compiler, {
publicPath: config.output.publicPath
}));
app.listen(3000, function () {
console.log('listening on port 3000');
});
为了看到页面效果,修改index1.js:
function write() {
document.write('hello webpack-dev-middleware');
}
write();
修改package.json,在script脚本中添加命令:
"server": "node server.js",
运行 npm run server
,构建成功后,在浏览器中打开http://localhost:3000,就会看到页面。修改源文件,然后刷新浏览器,就会看到修改后的结果。