Webpack4 入門到帶你打包一個簡單單頁應用專案
正文前先吐槽下, webpack 對新手入門真的有點不友好,各個版本在配置上都有或多或少的差異,導致在對照各種教程學習的過程中免不了掉進各種坑裡,所以寫這篇文章旨在簡單明瞭的解釋說明 webpack 的各種常用配置,希望能讓新人接觸 webpack 時少走些彎路。
一、搭建專案
1. 我們先新建一個專案 project 並用 npm 命令初始化專案(一路回車)
npm init
2. 安裝 webpack 與 webpack-cli ( 4 版本需要cli才能執行命令)
npm install --save-dev webpack webpack-cli
3. 新建 src 資料夾,存放我們要打包的原始碼,預設輸入檔案是 index.js,所以我們在 src 下新建一個index.js檔案
document.write("測試檔案打包")
4. 執行命令,便能實現最簡單的 “ 專案打包 ”
webpack
5. 輸入命令打包完成後會生成一個 dist 資料夾,裡面就存放著我們需要打包的檔案,這樣一個最簡單的 webpack 打包流程到此完工,接下來就要進入正片了。
二、命令部分
1. webpack 預設打包命令
第一部分我們使用過 webpack 命令進行打包,其實這個命令是不完整的,細心的小夥伴會發現執行時控制檯會有提示該命令有 production(生產) 與 development (開發)模式,完整命令如下:
// 兩個命令有和不同就請大家自己手動試一下,這裡就不贅述了 webpack --mode production webpack --mode development
2. webpack 根據配置檔案打包命令
實際中我們打包專案根據需要會有各種配置,因此常用的是根據配置檔案來進行打包,所以我們在專案根目錄下新建一個 webpack.conf.js 檔案來儲存配置資訊
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
}
}
稍後會對這個檔案進行詳細講解,這裡先執行命令看是否能成功進行按需打包
// webpack.conf.js 可根據自己需要命名 打包方法是 --config 配置檔案路徑 webpack --mode production --config ./webpack.conf.js
打包成功會發現在 dist 下現在生成的檔名已經由預設變成了我們指定的 bundle.js
3. 改寫 npm 命令
由於 webpack 指令比較長,輸入時很不方便,我們有個小技巧可以簡化這一步驟,就是對專案的 package.json 檔案中的 script 部分進行修改
"scripts": {
"dev": "webpack --mode development --config ./webpack.conf.js",
"build": "webpack --mode production --config ./webpack.conf.js"
},
然後執行以下命令就相當於執行了我們所設定對應的完整 webpack 命令
npm run dev
npm run build
三、配置部分
這部分會涉及很多內容,包括一些常用外掛,我會逐步帶大家完善 webpack.conf.js 檔案,但基本點到即止,詳細配置還需參考官方文件自行配置
1. 關於檔案路徑
配置檔案會有許多關於檔案路徑的設定,這方面一不小心就會出現問題,這裡推薦採以下方法對相對路徑進行處理
const path = require('path')
// 此方法會根據傳入的相對路徑自動轉化為絕對路徑,確保路徑的正確
path.resolve(__dirname, '檔案的相對路徑')
- webpack.conf.js 配置例子
const path = require('path')
module.exports = {
entry: path.resolve(__dirname, './src/index.js'),
output: {
filename: 'main.js',
}
}
2. 配置檔案結構總覽
主要包含以下 4 個部分 entry:配置檔案入口 output:配置輸出檔名與路徑 plugins:配置引入的外掛 module: 配置檔案轉換的規則
const path = require('path')
module.exports = {
// 輸入路徑配置
entry: path.resolve(__dirname, './src/index.js'),
// 輸出檔名和路徑配置
output: {
filename: 'main.js',
path: path.resolve(__dirname, './dist')
},
// 引入外掛配置
plugins: [],
// 檔案型別轉換配置
module: {}
}
對檔案結構有個總體瞭解後我們接下來就開始逐步完善
3. 完善 js 檔案輸出路徑
通常專案我們有一個專門的 js 資料夾進行存放 js 檔案,並且為了區分版本,我們有時會使用 hash 進行區分( hash 值僅當原始碼檔案被修改時才會更新)
- webpack.conf.js 配置例子
const path = require('path')
module.exports = {
// 輸入路徑配置
entry: path.resolve(__dirname, './src/index.js'),
// 輸出檔名和路徑配置
output: {
// [name] 可自行配置,參考文件
// [hash:4] 使用 hash 取前 4 位
filename: 'js/[name]-[hash:4].js',
path: path.resolve(__dirname, './dist')
},
// 引入外掛配置
plugins: [],
// 檔案型別轉換配置
module: {}
}
4. 使用外掛,引入 html 模板
目前為止,我們打包的都只有 js 檔案,作為前端專案,怎麼可以沒有 html 檔案呢,為了實現打包自動生成 html 檔案,我們開始引入我們的第一個外掛
- 安裝外掛 html-webpack-plugin
npm install --save-dev html-webpack-plugin
- 在專案根目錄下新建 index.html 檔案作為模板,供配置檔案引入
- webpack.conf.js 配置例子
const path = require('path')
const htmlWebpackPlugins = require('html-webpack-plugin')
module.exports = {
// 輸入路徑配置
entry: path.resolve(__dirname, './src/index.js'),
// 輸出檔名和路徑配置
output: {
filename: 'js/main.js',
path: path.resolve(__dirname, './dist')
},
// 引入外掛配置
plugins: [
new htmlWebpackPlugins({
// 輸出檔名
filename: 'index.html',
// 所引用模板檔案位置
template: 'index.html',
// js 檔案插入的位置
inject: 'body'
}),
],
// 檔案型別轉換配置
module: {}
}
現在嘗試下打包,基本的 html 和 js 檔案就有了,但這遠遠還不夠,我們還需要對 html 與 js 的相關配置進行處理,為了使專案更完整,我們還要新建一些檔案。
5. 完善專案目錄
- 在 src 目錄下新建 components 資料夾,分別新建 html, js, css 檔案 ,下面以 scroll 元件為例
scroll.html
<div class="scroll">
<p>scroll</p>
</div>
scroll.js
// import tpl from './scroll.html'
// import './scroll.css'
function scroll () {
return {
name: 'scroll',
// tpl: tpl
}
}
export default scroll
scroll.css
.scroll {
height: 500px;
width: 500px;
background: red;
}
.scroll p {
display: flex;
}
- 檔案新建完還需在我們的入口檔案 index.js 中引入
import Scroll from './components/scroll'
const App = function () {
var dom = document.getElementById('app')
var scroll = new Scroll()
dom.innerHTML = scroll.tpl
document.write(scroll.name)
}
new App()
- 最後修改下我們的 index.html 模板,新增 app 模組
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
這時嘗試打包,便可把我們新增的 scroll.js 引入進來了,但是這時我們 tpl 也就是 scroll.html 還處於註釋狀態,想要正確引入,還需新增其他外掛
6. 使用外掛,配對 .html 型別檔案(之後的 .css, .png等其他型別的檔案引入方法與此類似)
- 安裝外掛 html-loader
npm install --save-dev html-loader
- 修改我們的 webpack.conf.js ,在 module 中完善我們的檔案轉換配置
const path = require('path')
const htmlWebpackPlugins = require('html-webpack-plugin')
module.exports = {
entry: path.resolve(__dirname, './src/index.js'),
output: {
filename: 'js/main.js',
path: path.resolve(__dirname, './dist')
},
plugins: [
new htmlWebpackPlugins({
filename: 'index.html',
template: 'index.html',
inject: 'body'
}),
],
// 檔案型別轉換配置
module: {
rules: [
{
// 正則匹配 html 檔案
test: /\.html$/,
use: [
{
// 引入 html 檔案載入外掛
loader: 'html-loader'
}
]
}
]
}
}
- 修改下我們的 scroll.js 檔案,將之前的註釋取消
import tpl from './scroll.html'
// import './scroll.css'
function scroll () {
return {
name: 'scroll',
tpl: tpl
}
}
export default scroll
- OK ~ 嘗試打包,現在應該就能正確的把 scroll.thml 的內容也打包進去了,成功之後我們就只剩 .css 型別檔案沒有打包進去,那麼繼續我們的配置
7. 使用外掛,配對 .css 型別檔案
- 安裝外掛 css-loader 與 style-loader
npm install --save-dev css-loader style-loader
- 修改我們的 webpack.conf.js, 新增匹配規則
const path = require('path')
const htmlWebpackPlugins = require('html-webpack-plugin')
module.exports = {
// 輸入路徑配置
entry: path.resolve(__dirname, './src/index.js'),
// 輸出檔名和路徑配置
output: {
filename: 'js/main.js',
path: path.resolve(__dirname, './dist')
},
// 引入外掛配置
plugins: [
new htmlWebpackPlugins({
filename: 'index.html',
template: 'index.html',
inject: 'body'
}),
],
// 檔案型別轉換配置
module: {
rules: [
{
// 正則匹配 html 檔案
test: /\.html$/,
use: [
{
// 引入 html 檔案載入外掛
loader: 'html-loader'
}
]
},
{
// 正則匹配 css 檔案
test: /\.css$/,
use: [
{
// 引入 style 檔案載入外掛
loader: 'style-loader'
},
{
// 引入 css 檔案載入外掛
loader: 'css-loader'
}
]
},
]
}
}
- 修改下我們的 scroll.js 檔案,將之前 css 的註釋也取消
import tpl from './scroll.html'
import './scroll.css'
function scroll () {
return {
name: 'scroll',
tpl: tpl
}
}
export default scroll
- 進行打包,成功後自己看看效果,這樣一個簡單 webpack 打包流程就已經走完了
至此,相信你對 webpack 的基本工作流程有了一定的瞭解,不過這只是剛剛開始,上面的例子離我們實際工作中的應用還有一段距離,例如 js 沒有實現 ES6 到 ES5 的轉換,css 樣式不是以一個檔案的形式插入,遇到引入圖片檔案時上面的配置會出現錯誤,還有許多我們常用的框架檔案如 vue 等檔案型別要打包時都是需要重新配置的,本文就不再對配置進行深究,只是簡單多介紹一些常用外掛供大家學習瞭解
8. 外掛介紹
- babel-loader , babel-preset-latest , babel-core 用於ES6 到 ES5 的轉換
- autoprefixer , postcss-loader 用於 css 根據配置的瀏覽器版本進行自動新增字首
- less, less-loader 用於試別 less 型別樣式檔案(sass等同理,引入相應外掛進行配置)
- url-loader 用於載入圖片型別檔案
- image-webpack-loader 用於優化圖片檔案載入
- mini-css-extract-plugin 用於分離壓縮 css 檔案