本文主要分為:
- 環(huán)境配置
- 使用配置文件
- CSS 處理
- ES6 代碼編輯
- 文件壓縮
- SASS 處理
- CSS 與 JS 分離
- 文件處理 file-loader 與 url-loader
- 多入口及自動清理
客位看官可直接 ctrl + f 搜索對應關鍵字
環(huán)境配置
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
增加執(zhí)行腳本語句 -
打包
# 命令語句 源文件 目標文件 npm run start src/main.js dist/bundle.js
如果沒有 dist 目錄則自動新建

-
打包結果
打包后 在
webpack-3.10.0目錄下創(chuàng)建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文件的內容時,刷新頁面并不會顯示更新的改動,如果想讓頁面同步的話,我們還需再執(zhí)行一次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" }, - 方法一:修改

以第二種方式為例:

此時則監(jiān)聽成功,修改
main.js 保存則實時會在 bundle.js 中顯示,頁面中刷新即可展示;ctrl + c 終止監(jiān)聽。

使用配置文件
- 為了看出效果,我們先把之前生成的
bundle.js文件刪掉。 - 在
webpack-3.10.0目錄下創(chuàng)建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", -
跑一下
跑跑
同樣是創(chuàng)建了 bundle.js 文件
效果是一樣的
CSS 處理
- 在
src目錄下創(chuàng)建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會發(fā)現bundle.js中的代碼依舊為ES6
尚未安裝 ES6 - 這時需要 Babel 這個工具
Babel 的作用就是將下一代的 JavaScript 語法轉換為現今瀏覽器兼容的語句
- 首先安裝
Babelnpm install --save-dev babel-loader babel-core - 在
webpack.config.js中添加一條規(guī)則:
其中,{ test: /\.js$/, exclude: /node_modules/, loader: "babel-loader" }test用于判斷擴展名為.js的文件,exclude表示不包括的文件。
添加規(guī)則后,此時的webpack.config.js文件應該是這樣的
添加規(guī)則 - 安裝轉換
ES2015及更高版本JavaScript語法的 env presetnpm install babel-preset-env --save-dev - 在根目錄
webpack-3.10.0下創(chuàng)建.babelrc文件,內容如下:{ "presets": ["env"] }

- OK,現在執(zhí)行命令
npm run watch,可以看到我們之前main.js中的語句在bundle.js中已經成功轉換成通用語句了
main.js
bundle.js
本節(jié)內容可直接參考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

- 然而我們在開發(fā)調試階段是不需要壓縮代碼的,因此需要對開發(fā)環(huán)境和線上環(huán)境做個區(qū)分,開發(fā)環(huán)境不壓縮代碼,線上環(huán)境才壓縮
如果是線上環(huán)境,則將if(process.env.NODE_ENV === 'production'){ module.exports.plugins.push(new webpack.optimize.UglifyJsPlugin()) }UngifyJsPlugin插件填入webpack的plugins中 - 回到命令行調用命令
set NODE_ENV=production // 設置為生產環(huán)境, windows 系統(tǒng) npm run watch

- 我們可以直接在
package.json中添加腳本命令(我嘗試了幾種寫法,發(fā)現只有這樣是有效的,不知道為什么。此外,有時這樣也不好用,需要在命令行中手動制定一次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 即可切換為開發(fā)環(huán)境(代碼不壓縮),npm run production 就是生產環(huán)境(代碼壓縮)

- 對
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 }] } -
執(zhí)行
npm run production,圖片被打包并以hash方式重新命名
圖片打包
打包后的 main.css -
也可以讓圖片以原有名字和后綴保存:
{ test:/\.png|jpe?g|gif$/, use:[{ loader:'file-loader', options:{ name:'[name].[ext]' // 以原有名字和后綴保存 } }] }

- 也可以創(chuàng)建指定目錄存放文件
或,注意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值會發(fā)現,每次打包由于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')
}
};






















