目录
三、webpack-dev-middleware + express
在前面文章的介绍使用webpack的过程中,我们每次需要打包源代码时,都需要在命令行中手动运行npm run bundle(脚本命令)进行打包。也就是每改一次源代码,都需要手动打包一次,这样就很麻烦。
那么webpack有没有帮我们自动打包的机制呢?有的。。。。
webpack有几种不同的选项,能够在代码发生变化后自动打包代码:
- webpack's Watch Mode —— 观察模式
- webpack-dev-server —— 简单web服务器
- webpack-dev-middleware —— 简单web服务器
一、观察模式
webpack的观察模式能够在源代码改变时,自动进行代码重新打包。
首先,需要添加一个用于启动webpack的观察模式的npm script脚本:
package.json:
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "",
"private": true,
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"bundle": "webpack",
"watch": "webpack --watch"
},
"author": "ag_dubs <wombat@npmjs.com>",
"license": "ISC",
"devDependencies": {
"autoprefixer": "^9.5.1",
"clean-webpack-plugin": "^2.0.2",
"css-loader": "^2.1.1",
"file-loader": "^3.0.1",
"html-webpack-plugin": "^3.2.0",
"node-sass": "^4.12.0",
"postcss-loader": "^3.0.0",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"stylus": "^0.54.5",
"url-loader": "^1.1.2",
"webpack": "^4.31.0",
"webpack-cli": "^3.3.2"
}
}
修改webpack.config.js:
webpack.config.js:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 导入HtmlWebpackPlugin
const CleanWebpackPlugin = require('clean-webpack-plugin'); // 导入CleanWebpackPlugin
module.exports = {
mode: 'development',
devtool: 'cheap-module-eval-source-map',
entry: {
main: './src/index.js',
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.(png|svg|jpg|gif$)/, // 文件后缀名匹配通配符
use: [{
loader: 'url-loader', // 使用的loader
options: {
limit: 10240 // 当图片小于10kb时,使用base64的方式进行打包
}
}]
},
{
test: /\.scss$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 2
}
},
'sass-loader',
'postcss-loader'
]
},
{
test: /\.(woff|woff2|eot|ttf)$/,
use: [
'file-loader'
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
filename: 'dist.html', // 将自动生成的html文件的文件名改为dist.html
template: './src/template.html' // 模板
}),
new CleanWebpackPlugin()
]
};
修改index.js:
index.js:
console.log('hello world!');
然后使用npm run watch脚本命令进行打包:
使用浏览器打开dist.html:
控制台打印了"hello world!"。
现在修改index.js:
index.js:
console.log('hello webpack!');
然后刷新浏览器(注意没有进行重新打包操作),可以看到控制台:
浏览器控制台也成功打印了"hello webpack!"。
说明webpack在观察模式下会监听源代码,源代码一发生变化就自动进行重新打包操作。
但是观察模式有一个唯一的缺点:为了看到修改后的实际效果,我们需要手动刷新浏览器。
webpack-dev-server不仅能自动打包,还可以实现自动刷新浏览器的功能。
二、webpack-dev-server
webpack的webpack-dev-server其实是在为我们构建了一个简单的web服务器,能够实时监听我们的代码变化,并能自动进行源代码打包。
使用webpack-dev-server需要先安装webpack-dev-server:
然后修改webpack.config.js:
webpack.config.js:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 导入HtmlWebpackPlugin
const CleanWebpackPlugin = require('clean-webpack-plugin'); // 导入CleanWebpackPlugin
module.exports = {
mode: 'development',
devtool: 'cheap-module-eval-source-map',
entry: {
main: './src/index.js',
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist')
},
devServer: {
contentBase: './dist' // 告诉dev-server在哪里查找文件
},
module: {
rules: [
{
test: /\.(png|svg|jpg|gif$)/, // 文件后缀名匹配通配符
use: [{
loader: 'url-loader', // 使用的loader
options: {
limit: 10240 // 当图片小于10kb时,使用base64的方式进行打包
}
}]
},
{
test: /\.scss$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 2
}
},
'sass-loader',
'postcss-loader'
]
},
{
test: /\.(woff|woff2|eot|ttf)$/,
use: [
'file-loader'
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
filename: 'dist.html', // 将自动生成的html文件的文件名改为dist.html
template: './src/template.html' // 模板
}),
new CleanWebpackPlugin()
]
};
上面的devServer的配置告知webpack-dev-server,在localhost:8080下建立服务,将dist目录下的文件,作为可访问文件。
接下来,还要添加一个npm script 脚本,用于直接运行webpack-dev-server服务器:
package.json:
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "",
"private": true,
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"bundle": "webpack",
"watch": "webpack --watch",
"server": "webpack-dev-server"
},
"author": "ag_dubs <wombat@npmjs.com>",
"license": "ISC",
"devDependencies": {
"autoprefixer": "^9.5.1",
"clean-webpack-plugin": "^2.0.2",
"css-loader": "^2.1.1",
"file-loader": "^3.0.1",
"html-webpack-plugin": "^3.2.0",
"node-sass": "^4.12.0",
"postcss-loader": "^3.0.0",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"stylus": "^0.54.5",
"url-loader": "^1.1.2",
"webpack": "^4.31.0",
"webpack-cli": "^3.3.2",
"webpack-dev-server": "^3.6.0"
}
}
然后使用npm run server进行打包,并开启webpack-dev-server服务器:
打开浏览器,在地址栏输入http://localhost:8080/dist.html:
控制台成功打印了hello webpack!。
接下来,修改index.js:
index.js:
console.log('hello world!');
我们可以看到,浏览器无需刷新而成功打印出hello world!:
刚才webpack-dev-server服务器是在8080的端口号上构建的,我们也可以修改成其他端口号:
webpack.config.js:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 导入HtmlWebpackPlugin
const CleanWebpackPlugin = require('clean-webpack-plugin'); // 导入CleanWebpackPlugin
module.exports = {
mode: 'development',
// devtool: 'cheap-module-eval-source-map',
entry: {
main: './src/index.js',
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist')
},
devServer: {
contentBase: './dist', // 告诉dev-server在哪里查找文件
port: '8085' // 端口号
},
module: {
rules: [
{
test: /\.(png|svg|jpg|gif$)/, // 文件后缀名匹配通配符
use: [{
loader: 'url-loader', // 使用的loader
options: {
limit: 10240 // 当图片小于10kb时,使用base64的方式进行打包
}
}]
},
{
test: /\.scss$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 2
}
},
'sass-loader',
'postcss-loader'
]
},
{
test: /\.(woff|woff2|eot|ttf)$/,
use: [
'file-loader'
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
filename: 'dist.html', // 将自动生成的html文件的文件名改为dist.html
template: './src/template.html' // 模板
}),
new CleanWebpackPlugin()
]
};
重新使用npm run server命令重启服务器:
可以看到端口改变成8085。
三、webpack-dev-middleware + express
除了使用流行的webpack-dev-server,还可以使用webpack-dev-middleware配合express server构建简单的web服务器。
webpack-dev-middleware是一个容器(wrapper),它可以把webpack处理后的文件传递给一个服务器(server)。webpack-dev-server在内部使用了它,同时,它也可以作为一个单独的包来使用,以便进行更多自定义设置来实现更多的需求。
接下来使用webpack-dev-middleware + express server构建简单的web服务器。
首先,安装webpack-dev-middleware和express:
然后在webpack-demo的根目录下新建一个server.js文件用于设置自定义的express服务:
server.js:
const express = require('express');
const webpackDevMiddleware = require('webpack-dev-middleware');
const webpack = require('webpack');
const config = require('./webpack.config.js');
// webpack编译器
const compiler = webpack(config);
// 实例化一个express实例
const app = express();
// 告诉express使用webpack-dev-middleware
app.use(webpackDevMiddleware(compiler, {
// 这里可以填写更多配置项
}));
// 在3000端口号上启动服务器
app.listen(3000, () => {
console.log('express server is running');
});
再添加一个npm script,用于运行服务:
package.json:
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "",
"private": true,
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"bundle": "webpack",
"watch": "webpack --watch",
"server": "webpack-dev-server",
"express": "node server.js"
},
"author": "ag_dubs <wombat@npmjs.com>",
"license": "ISC",
"devDependencies": {
"autoprefixer": "^9.5.1",
"clean-webpack-plugin": "^2.0.2",
"css-loader": "^2.1.1",
"express": "^4.17.1",
"file-loader": "^3.0.1",
"html-webpack-plugin": "^3.2.0",
"node-sass": "^4.12.0",
"postcss-loader": "^3.0.0",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"stylus": "^0.54.5",
"url-loader": "^1.1.2",
"webpack": "^4.33.0",
"webpack-cli": "^3.3.3",
"webpack-dev-middleware": "^3.7.0",
"webpack-dev-server": "^3.4.0"
}
}
现在,可以使用npm script运行服务:
使用浏览器打开http://localhost:3000/dist.html,可以发现控制台也打印成功: