本文主要分为:
- 环境配置
- 使用配置文件
- CSS 处理
- ES6 代码编辑
- 文件压缩
- SASS 处理
- CSS 与 JS 分离
- 文件处理 file-loader 与 url-loader
- 多入口及自动清理
客位看官可直接 ctrl + f 搜索对应关键字
环境配置
window + r,输入cmd打开命令行-
新建并进入
webpack-3.10.0文件夹mkdir webpack-3.10.0 && cd webpack-3.10.0 -
使用
sublime text3的subl.exe打开该文件夹
subl.exe -
在
webpack-3.10.0目录下初始化操作,生成package.json文件npm init -y
也可以直接使用 npm init 来初始化 package.json 文件,但这样需要手动填写项目名之类的东西,加上 -y 表示使用默认配置

-
新建
src文件夹,今后将要打包的文件全部放入该文件夹下
新建 src 文件夹 -
在
src下新建main.js并随便敲一点代码
main.js -
安装
webpacknpm install webpack@3.10.0 --save-dev
这里是安装指定版本号的 webpack,不加版本号则是最新版

安装完成后的 package.json

安装完成后的项目目录

-
修改
package.json
增加执行脚本语句 -
打包
# 命令语句 源文件 目标文件 npm run start src/main.js dist/bundle.js
如果没有 dist 目录则自动新建

-
打包结果
打包后 在
webpack-3.10.0目录下创建index.html文件,引入之前打包好的bundle.js文件
<!DOCTYPE html>
<html>
<head>
<title>webpack-3.10.0</title>
</head>
<body>
<h1>Hello World!</h1>
<script type="text/javascript" src="dist/bundle.js"></script>
</body>
</html>

- 我们同样可以把打包的语句直接写在
package.json中,免得每次输入很麻烦"start":"webpack src/main.js dist/bundle.js"

这样我们在命令行中直接调用
npm run start 也能实现打包的效果
- 现在有个问题,当我们修改
main.js文件的内容时,刷新页面并不会显示更新的改动,如果想让页面同步的话,我们还需再执行一次npm run start语句,每次这样未免太麻烦,可以通过以下几种方式改善:- 方法一:修改
package.json中之前写好的start语句
"start":"webpack src/main.js dist/bundle.js --watch",- 方法二:新定义一个
watch命令,这种方式根据官方文档说明,由于调用的是之前自定义的npm run start命令,因此需要在--watch前额外添加--
# package.json "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start":"webpack src/main.js dist/bundle.js", "watch":"npm run start -- --watch" }, - 方法一:修改

以第二种方式为例:

此时则监听成功,修改
main.js 保存则实时会在 bundle.js 中显示,页面中刷新即可展示;ctrl + c 终止监听。

使用配置文件
- 为了看出效果,我们先把之前生成的
bundle.js文件删掉。 - 在
webpack-3.10.0目录下创建webpack.config.js,并输入如下内容
# webpack.config.js
var webpack = require("webpack");
module.exports = {
entry:'./src/main.js',
output:{
path:'./dist',
filename:'bundle.js'
}
}
此时你的项目结构应该是这样的,dist 目录下 空空如也:

-
跑一下试试
报错
原因是output中的路径需要是绝对路径absolute path -
在配置文件中引入
path模块解决绝对路径问题var webpack = require("webpack"); var path = require("path"); module.exports = { entry:'./src/main.js', output:{ path:path.resolve(__dirname,'./dist'), filename:'bundle.js' } } -
由于添加了配置文件,因此需要修改一下
package.json中的启动命令npm run start更改为如下(因为配置文件中已经设置了路径及文件名,因此不需要命令中再指定)"start":"webpack", -
跑一下
跑跑
同样是创建了 bundle.js 文件
效果是一样的
CSS 处理
- 在
src目录下创建main.css# main.css body{ background: orange; } - 修改
main.js# main.js require('./main.css') - 使用
npm run watch命令会报错
缺少 loader
缺少loader,这里引用官网说明:
loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后你就可以利用 webpack 的打包能力,对它们进行处理。
本质上,webpack loader 将所有类型的文件,转换为应用程序的依赖图(和最终的 bundle)可以直接引用的模块。
- 处理
css需要安装一个css-loader的包:npm install css-loader --save-dev

- 安装完成后需要在配置文件中进行处理,注意
module属性:
# webpack.config.js
var webpack = require("webpack");
var path = require("path");
module.exports = {
entry:'./src/main.js',
output:{
path:path.resolve(__dirname,'./dist'),
filename:'bundle.js'
},
module:{
rules:[{
test:/\.css$/, // 正则匹配 .css 后缀
use:'css-loader'
}]
}
}
再跑一下

看一下是否被打包到
bundle.js 中
可以看到
main.css 的样式的确被打包到 bundle.js 中了,但为什么浏览器中没有效果?
- 安装
style-loader
npm install style-loader --save-dev
- 修改配置文件,注意:
style-loader需要写在前面
修改配置文件 - 再调用命令
npm run watch

将 ES6 代码编辑为所有浏览器通用的代码
- 将
main.js内容改为一段ES6的代码# main.js let a = 11; const b = 22; class Foo{ } - 直接调用
npm run watch会发现bundle.js中的代码依旧为ES6
尚未安装 ES6 - 这时需要 Babel 这个工具
Babel 的作用就是将下一代的 JavaScript 语法转换为现今浏览器兼容的语句
- 首先安装
Babelnpm install --save-dev babel-loader babel-core - 在
webpack.config.js中添加一条规则:
其中,{ test: /\.js$/, exclude: /node_modules/, loader: "babel-loader" }test用于判断扩展名为.js的文件,exclude表示不包括的文件。
添加规则后,此时的webpack.config.js文件应该是这样的
添加规则 - 安装转换
ES2015及更高版本JavaScript语法的 env presetnpm install babel-preset-env --save-dev - 在根目录
webpack-3.10.0下创建.babelrc文件,内容如下:{ "presets": ["env"] }

- OK,现在执行命令
npm run watch,可以看到我们之前main.js中的语句在bundle.js中已经成功转换成通用语句了
main.js
bundle.js
本节内容可直接参考Babel官网:https://babeljs.cn/
文件压缩
- 文件压缩需要用
webpack的插件来实现,比如webpack自带一个BannerPlugin插件,用于添加顶部注释,首先在webpack.config.js中添加如下代码:plugins:[ new webpack.BannerPlugin('顶部注释插件') ] - 重新打包
npm run watch,成功后,bundle.js中顶部出现注释
添加成功 -
webpack有个自带的插件UglifyJsPlugin用于压缩文件
plugins:[
new webpack.BannerPlugin('顶部注释插件'),
new webpack.optimize.UglifyJsPlugin()
]
重新打包后的 bundle.js

- 然而我们在开发调试阶段是不需要压缩代码的,因此需要对开发环境和线上环境做个区分,开发环境不压缩代码,线上环境才压缩
如果是线上环境,则将if(process.env.NODE_ENV === 'production'){ module.exports.plugins.push(new webpack.optimize.UglifyJsPlugin()) }UngifyJsPlugin插件填入webpack的plugins中 - 回到命令行调用命令
set NODE_ENV=production // 设置为生产环境, windows 系统 npm run watch

- 我们可以直接在
package.json中添加脚本命令(我尝试了几种写法,发现只有这样是有效的,不知道为什么。此外,有时这样也不好用,需要在命令行中手动制定一次set NODE_ENV=production,之后调用npm run production就有效了)"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "webpack", "watch": "npm run start -- --watch", "production":"set NODE_ENV=production && npm run watch", "development":"set NODE_ENV=development && webpack --watch" }
这样在命令行中通过 npm run development 即可切换为开发环境(代码不压缩),npm run production 就是生产环境(代码压缩)

- 对
webpack.config.js简单做一下整理
var webpack = require("webpack");
var path = require("path");
var isProduction = process.env.NODE_ENV === 'production'
module.exports = {
entry:'./src/main.js',
output:{
path:path.resolve(__dirname,'./dist'),
filename:'bundle.js'
},
module:{
rules:[{
test:/\.css$/,
use:['style-loader','css-loader']
},{
test: /\.js$/, exclude: /node_modules/, loader: "babel-loader"
}]
},
plugins:[
new webpack.BannerPlugin('顶部注释插件'),
]
}
if(isProduction){
module.exports.plugins.push(new webpack.optimize.UglifyJsPlugin())
}
SASS 处理
- 安装相关
loadernpm install sass-loader node-sass webpack --save-dev - 这里我在安装
node-sass时失败了,改为分别单独安装,node-sass使用淘宝镜像 其他解决方案# 安装 sass-loader npm install sass-loader --save-dev # 安装 node-sass npm i node-sass --sass_binary_site=https://npm.taobao.org/mirrors/node-sass/ - 修改配置文件
# webpack.config.js module:{ rules:[{ test: /\.scss$/, use: [ "style-loader", // creates style nodes from JS strings "css-loader", // translates CSS into CommonJS "sass-loader" // compiles Sass to CSS ] },{ test:/\.css$/, use:['style-loader','css-loader'] },{ test: /\.js$/, exclude: /node_modules/, loader: "babel-loader" }] }, - 修改
mian.js# main.js require('./main.scss') - 修改
main.css为main.scss并输入scss语句测试# main.scss $default:pink; body{ background:$default }
重新打包,OK

CSS 与 JS 分离
- 通常
webpack建议所有文件都打包成一个单独的文件,这样可以减少网络请求。但如果有需要分类打包的话,需要使用webpack的一个外部插件 ExtractTextWebpackPlugin - 安装
npm install --save-dev extract-text-webpack-plugin - 修改配置文件,注意注释部分
var webpack = require("webpack");
var ExtractTextPlugin = require("extract-text-webpack-plugin"); // 引入插件
var path = require("path");
var isProduction = process.env.NODE_ENV === 'production';
module.exports = {
entry:'./src/main.js',
output:{
path:path.resolve(__dirname,'./dist'),
filename:'[name].js'
},
module:{
rules:[{
test: /\.scss$/,
use: ExtractTextPlugin.extract({ // 使用插件
fallback: "style-loader", // 用哪个 loader 加载
use: [{
loader:"css-loader",
options:{
minimize:isProduction // 是否压缩 css
}},
"sass-loader"] // 将资源转换为 css
})
},{
test: /\.js$/, exclude: /node_modules/, loader: "babel-loader"
}]
},
plugins:[
new webpack.BannerPlugin('顶部注释插件'),
new ExtractTextPlugin("[name].css"), // 输出为 style.css 文件
]
}
if(isProduction){
module.exports.plugins.push(new webpack.optimize.UglifyJsPlugin())
}
文件处理 file-loader 与 url-loader
-
首先在
src目录下新建images目录并存入两个大小不一的图片
新建目录并存入图片 -
在
index.html及main.scss中引入两个图片
index.html
main.scss -
安装
file-loadernpm install --save-dev file-loader -
修改配置文件
module:{ rules:[{ test: /\.scss$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: [{ loader:"css-loader", options:{ minimize:isProduction }}, "sass-loader"] }) },{ test: /\.js$/, exclude: /node_modules/, loader: "babel-loader" },{ test:/\.png|jpe?g|gif$/, // 匹配的图片格式 use:['file-loader'] // 使用 file-loader }] } -
执行
npm run production,图片被打包并以hash方式重新命名
图片打包
打包后的 main.css -
也可以让图片以原有名字和后缀保存:
{ test:/\.png|jpe?g|gif$/, use:[{ loader:'file-loader', options:{ name:'[name].[ext]' // 以原有名字和后缀保存 } }] }

- 也可以创建指定目录存放文件
或,注意options:{ name:'images/[name].[ext]' }outputPath的/不能少options:{ name:'[name].[ext]', outputPath:'images/' }效果就是这样
我是效果 - 至于
url-loader,它可以限制图片的大小,小于一定值的图片将以DataURL直接嵌入在页面中,减少请求数 - 安装
npm install --save-dev url-loader - 修改配置文件
use:[{ loader:'url-loader', options:{ limit:20480, // 小于该值将嵌入页面 name:'[name].[ext]', outputPath:'images/' } }] -
打包后可看到只有一个图片被打包,另一个图片直接嵌在了页面中:
只有一张图片引入
嵌入页面
多入口及自动清理
- 尝试改一下入口属性
entry:{app:'./src/main.js'},
这样生成的 js 和 css 文件将变成 app.js 和 app.css
- 先安装一个
jquery包,注意名字小写npm install --save-dev jquery - 修改配置文件
entry:{ main:'./src/main.js', // 将 main.js 打包成 main vendor:'jquery' // 将 jquery 打包成 vendor }

- 自动清理需要 clean-webpack-plugin 插件
npm install clean-webpack-plugin --save-dev - 如果我们在生成的文件中添加
hash值会发现,每次打包由于hash导致名字的不同,进而会出现不同名的同文件,这显然不是我想要的。这个插件就可以用于每次打包前先清除指定目录或文件,避免重复。
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
+ const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
entry: {
app: './src/index.js',
print: './src/print.js'
},
plugins: [
+ new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({
title: 'Output Management'
})
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
};






















