簡單使用
安裝
在命令行中依次輸入
mkdir webpack-demo
cd webpack-demo
// 創建 package.json,這裏會問一些問題,直接回車跳過就行
npm init
// 推薦這個安裝方式,當然你也安裝在全局環境下
// 這種安裝方式會將 webpack 放入 devDependencies 依賴中
npm install --save-dev webpack
然後按照下圖創建文件
在以下文件寫入代碼
// sum.js
// 這個模塊化寫法是 node 環境獨有的,瀏覽器原生不支持使用
module.exports = function(a, b) {
return a + b
}
// index.js
var sum = require('./sum')
console.log(sum(1, 2))
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script src="./build/bundle.js"></script>
</body>
</html>
現在我們開始配置最簡單的 webpack,首先創建 webpack.config.js
文件,然後寫入如下代碼
// 自帶的庫
const path = require('path')
module.exports = {
entry: './app/index.js', // 入口文件
output: {
path: path.resolve(__dirname, 'build'), // 必須使用絕對地址,輸出文件夾
filename: "bundle.js" // 打包後輸出文件的文件名
}
}
現在我們可以開始使用 webpack 了,在命令行中輸入
node_modules/.bin/webpack
沒問題的話你應該可以看到類似的樣子
可以發現原本兩個 JS 文件只有 100B,但是打包後卻增長到 2.66KB,這之中 webpack 肯定做了什麼事情,我們去 bundle.js
文件中看看。
把代碼簡化以後,核心思路是這樣的
var array = [(function () {
var sum = array[1]
console.log(sum(1, 2))
}),
(function (a,b) {
return a + b
})
]
array[0]() // -> 3
因爲 module.export
瀏覽器是不支持的,所以
webpack 將代碼改成瀏覽器能識別的樣子。現在將 index.html
文件在瀏覽器中打開,應該也可以看到正確的
log。
我們之前是在文件夾中安裝的 webpack,每次要輸入 node_modules/.bin/webpack
過於繁瑣,可以在 package.json
如下修改
"scripts": {
"start": "webpack"
},
然後再次執行 npm
run start
,可以發現和之前的效果是相同的。簡單的使用到此爲止,接下來我們來探索 webpack 更多的功能。
Loader
Loader 是 webpack 一個很強大功能,這個功能可以讓你使用很多新的技術。
Babel
Babel 可以讓你使用 ES2015/16/17 寫代碼而不用顧忌瀏覽器的問題,Babel 可以幫你轉換代碼。首先安裝必要的幾個 Babel 庫
npm i --save-dev babel-loader babel-core babel-preset-env
先介紹下我們安裝的三個庫
- babel-loader 用於讓 webpack 知道如何運行 babel
- babel-core 可以看做編譯器,這個庫知道如何解析代碼
- babel-preset-env 這個庫可以根據環境的不同轉換代碼
接下來更改 webpack-config.js
中的代碼
module.exports = {
// ......
module: {
rules: [
{
// js 文件才使用 babel
test: /\.js$/,
// 使用哪個 loader
use: 'babel-loader',
// 不包括路徑
exclude: /node_modules/
}
]
}
}
配置 Babel 有很多方式,這裏推薦使用 .babelrc 文件管理。
// ..babelrc
{
"presets": ["babel-preset-env"]
}
現在將之前 JS 的代碼改成 ES6 的寫法
// sum.js
export default (a, b) => {
return a + b
}
// index.js
import sum from './sum'
console.log(sum(1, 2))
執行 npm
run start
,再觀察 bundle.js
中的代碼,可以發現代碼被轉換過了,並且同樣可以正常
輸出3。
當然 Babel 遠不止這些功能,有興趣的可以前往官網自己探索。
處理圖片
這一小節我們將使用 url-loader
和 file-loader
,這兩個庫不僅可以處理圖片,還有其他的功能,有興趣的可以自行學習。
先安裝庫
npm i --save-dev url-loader file-loader
創建一個 images
文件夾,放入兩張圖片,並且在 app
文件夾下創建一個
js 文件處理圖片
,目前的文件夾結構如圖
// addImage.js
let smallImg = document.createElement('img')
// 必須 require 進來
smallImg.src = require('../images/small.jpeg')
document.body.appendChild(smallImg)
let bigImg = document.createElement('img')
bigImg.src = require('../images/big.jpeg')
document.body.appendChild(bigImg)
接下來修改 webpack.config.js
代碼
module.exports = {
// ...
module: {
rules: [
// ...
{
// 圖片格式正則
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
use: [
{
loader: 'url-loader',
// 配置 url-loader 的可選項
options: {
// 限制 圖片大小 10000B,小於限制會將圖片轉換爲 base64格式
limit: 10000,
// 超出限制,創建的文件格式
// build/images/[圖片名].[hash].[圖片格式]
name: 'images/[name].[hash].[ext]'
}
}
]
}
]
}
}
運行 npm
run start
,打包成功如下圖
可以發現大的圖片被單獨提取了出來,小的圖片打包進了 bundle.js
中。
在瀏覽器中打開 HTML 文件,發現小圖確實顯示出來了,但是卻沒有看到大圖,打開開發者工具欄,可以發現我們大圖的圖片路徑是有問題的,所以我們又要修改 webpack.config.js
代碼了。
module.exports = {
entry: './app/index.js', // 入口文件
output: {
path: path.resolve(__dirname, 'build'), // 必須使用絕對地址,輸出文件夾
filename: "bundle.js", // 打包後輸出文件的文件名
publicPath: 'build/' // 知道如何尋找資源
}
// ...
}
最後運行下 npm
run start
,編譯成功了,再次刷新下頁面,可以發現這次大圖被正確的顯示了。下一小節我們將介紹如何處理 CSS 文件。
處理 CSS 文件
添加 styles
文件夾,新增 addImage.css
文件,然後在該文件中新增代碼
img {
border: 5px black solid;
}
.test {border: 5px black solid;}
這一小節我們先使用 css-loader
和 style-loader
庫。前者可以讓
CSS 文件也支持impost
,並且會解析 CSS 文件,後者可以將解析出來的
CSS 通過標籤的形式插入到 HTML 中,所以後面依賴前者。
npm i --save-dev css-loader style-loader
首先修改 addImage.js
文件
import '../styles/addImage.css'
let smallImg = document.createElement('img')
smallImg.src = require('../images/small.jpeg')
document.body.appendChild(smallImg)
// let bigImg = document.createElement('img')
// bigImg.src = require('../images/big.jpeg')
// document.body.appendChild(bigImg)
然後修改 webpack.config.js
代碼
module.exports = {
// ...
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader',
{
loader: 'css-loader',
options: {
modules: true
}
}
]
},
]
}
}
運行下 npm
run start
,然後刷新頁面,可以發現圖片被正確的加上了邊框,現在我們來看一下 HTML 的文件結構
從上圖可以看到,我們在 addImage.css
文件中寫的代碼被加入到了 style
標籤中,並且因爲我們開啓了
CSS 模塊化的選項,所以 .test
被轉成了唯一的哈希值,這樣就解決了 CSS
的變量名重複問題。
但是將 CSS 代碼整合進 JS 文件也是有弊端的,大量的 CSS 代碼會造成 JS 文件的大小變大,操作 DOM 也會造成性能上的問題,所以接下來我們將使用 extract-text-webpack-plugin
插件將
CSS 文件打包爲一個單獨文件
首先安裝 npm
i --save-dev extract-text-webpack-plugin
然後修改 webpack.config.js
代碼
const ExtractTextPlugin = require("extract-text-webpack-plugin")
module.exports = {
// ....
module: {
rules: [
{
test: /\.css$/,
// 寫法和之前基本一致
loader: ExtractTextPlugin.extract({
// 必須這樣寫,否則會報錯
fallback: 'style-loader',
use: [{
loader: 'css-loader',
options: {
modules: true
}
}]
})
]
}
]
},
// 插件列表
plugins: [
// 輸出的文件路徑
new ExtractTextPlugin("css/[name].[hash].css")
]
}
運行下 npm
run start
,可以發現 CSS 文件被單獨打包出來了
但是這時候刷新頁面會發現圖片的邊框消失了,那是因爲我們的 HTML 文件沒有引用新的 CSS 文件,所以這裏需要我們手動引入下,在下面的章節我們會通過插件的方式自動引入新的文件。