webpack 是一個前端工程化打包工具,對於前端工程師來說 webpack 是一項十分重要的技能。下面我們就通過搭建一個 vue 項目來學習使用 webpack
主要環境:
- node v14.15.0
- npm v6.14.9
- webpack v5.10.0
- webpack-cli v4.2.0
- vue v2.6.12
本項目實現以下功能:
- 與
vue/cli
類似的基本目錄 - 支持
*.vue
,*.css
等文件 - 支持
es6
及以上語法 - 支持加載圖片
- 熱加載
構建項目基本目錄
執行npm init
並創建以下目錄
demo
├─ dist
├─ public
└─ src
安裝必要依賴
webpack 及相關插件
- webpack
npm install -D webpack webpack-cli
- webpack 本地服務器插件
npm install -D webpack-dev-server
- html 生成插件,它會將生成的 js 和 css 文件插入到 html 中
npm install -D html-webpack-plugin
- vue 插件
npm install -D vue-loader vue-template-compiler
- css 插件
npm install -D css-loader style-loader vue-style-loader
- 圖片插件
npm install -D file-loader url-loader
- babel 插件
npm install -D @babel/core @babel/cli @babel/preset-env babel-loader
,npm install @babel/polyfill
安裝 vue
npm install vue vue-router
搭建項目
簡單實現 webpack 打包
新建src/main.js
,並寫入:
console.log('Hello Webpack');
根目錄下新建webpack.config.js
,並寫入:
const path = require('path');
const config = {
entry: './src/main.js', // 定義入口文件
output: {
path: path.resolve(__dirname + '/dist'), // 打包生成文件地址,必須是絕對路徑
filename: '[name].build.js', // 生成的文件名
},
};
module.exports = config;
在package.json
中的scripts
中添加一個腳本:
{
...
"scripts": {
"build": "webpack --mode=production"
}
...
}
在命令行中執行npm run build
,此時項目目錄中出現了dist/main.build.js
,證明執行成功
js 文件打包成功后,需要一個 html 文件來引入這個 js 文件,這就需要用到我們一開始下載的html-webpack-plugin
首先新建public/index.html
創建一個基礎頁面:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>webpack搭建vue</title>
</head>
<body>
<!-- 如果瀏覽器禁止加載js腳本 -->
<noscript>
<strong>
We're sorry but this site doesn't work properly without JavaScript
enabled. Please enable it to continue.
</strong>
</noscript>
<div id="app"></div>
<!-- build后的文件會在這之后自動引入 -->
</body>
</html>
在public
下隨便放入一個圖標favicon.ico
,然后在webpack.config.js
中配置插件:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const config = {
...
plugins:[
new HtmlWebpackPlugin({
filename: 'index.html', // 生成的文件夾名
template: 'public/index.html', // 模板html
favicon: 'public/favicon.ico', // 圖標
}),
]
}
...
之后再次執行npm run build
,dist
下會生成index.html
,favicon.ico
,main.build.js
三個文件,通過瀏覽器打開index.html
,就可以發現控制台輸出了Hello Webpack
,頁面圖標也變成了自己設定的圖標,通過編輯器打開index.html
,我們會發現 webpack 幫助我們自動引入了favicon.ico
和main.build.js
:
<!DOCTYPE html>
<html>
<head>
...
<link rel="icon" href="favicon.ico" />
</head>
<body>
...
<script src="main.build.js"></script>
</body>
</html>
開啟熱加載
webpack 熱加載需要用到webpack-dev-server
,在開始我們已經安裝過了,在webpack.config.js
中配置:
const config = {
...
devServer: {
contentBase: path.join(__dirname, 'dist'), // html所在路徑
compress: true, // 是否壓縮
port: 3000, // 端口
hot: true, // 熱部署
open: true, // 打包完成后自動打開網頁
}
}
增加package.json
腳本:
{
...
"scripts": {
"build": "webpack --mode=production",
"serve": "webpack serve"
}
...
}
執行npm run serve
,打包成功后會自動打開網頁,並且當你修改src/main.js
或src/index.html
的內容的時候,瀏覽器會自動重新打包並刷新
配置 Vue
讓 webpack 打包*.vue
文件需要vue-loader
和vue-template-compiler
,同時為了 webpack 能夠解析 vue 中的 css 還需要用到css-loader
和vue-style-loader
,在webpack.config.js
配置以上插件:
...
const { VueLoaderPlugin } = require('vue-loader');
const config = {
...
// loaders
module: {
rules: [
{
// *.vue
test: /\.vue$/,
loader: 'vue-loader',
},
{
// `*.vue` 文件中的 `<style>` 塊以及普通的`*.css`
test: /\.css$/,
use: ['vue-style-loader', 'css-loader'],
},
],
},
plugins: [
...
new VueLoaderPlugin(),
],
...
};
...
配置完后新建src/App.vue
:
<template>
<div class="example">
{{ msg }}
</div>
</template>
<script>
export default {
data() {
return {
msg: 'Hello Webpack',
};
},
};
</script>
<style>
.example {
color: red;
}
</style>
修改src/main.js
:
import Vue from 'vue';
import App from './App.vue';
new Vue({
el: '#app',
render: (h) => h(App),
});
然后運行npm run serve
,即可看到頁面上顯示的Hello Webpack
配置圖片資源的加載
使用file-loader
或url-loader
加載,它們都是用於打包文件和圖片資源的,區別在於url-loader
封裝了file-loader
在訪問網站時如果圖片較多,會發很多 http 請求,會降低頁面性能。這個問題可以通過 url-loader
解決。url-loader
會將引入的圖片編碼,生成 dataURl。相當於把圖片數據翻譯成一串字符,再把這串字符打包到文件中,最終只需要引入這個文件就能訪問圖片了。
當然,如果圖片較大,編碼會消耗性能。因此 url-loader
提供了一個 limit 參數,小於 limit 字節的文件會被轉為 DataURl,大於 limit 的還會使用 file-loader 進行 copy。
此處我們使用 url-loader
,由於它是基於 file-loader
的封裝,所以也需要引入 file-loader
。
...
const config = {
...
module: {
rules: [
...
{
// 圖片
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
use: {
loader: 'url-loader',
options: {
limit: 25000,
},
},
},
],
},
};
...
然后添加一個圖片src/assets/logo.png
,在App.vue
中引入:
<template>
<div class="example">
{{ msg }}
<img :src="url" />
</div>
</template>
<script>
import logo from './assets/logo.png';
export default {
data() {
return {
msg: 'Hello Vue1',
url: logo,
};
},
};
</script>
<style>
.example {
color: red;
}
</style>
再次npm run serve
即可看到圖片
配置 babel
babel 可以將 js 的高版本(es6)語法轉換為低版本,使得項目兼容低版本瀏覽器
需要我們注意的是,babel7 與 babel6 不兼容,因此需要使用最新版本的 babel 和 babel 插件,在前面文章開始我們已經安裝了 babel7 版本的 babel 插件,下面我們在webpack.config.js
中配置它:
...
const config = {
entry: ['@babel/polyfill', './src/main.js'],
...
module: {
rules: [
...
{
// *.js
test: /\.js$/,
exclude: /node_modules/, // 不編譯node_modules下的文件
loader: 'babel-loader',
},
],
},
};
...
配置完后在項目根目錄下創建一個 babel 的配置文件.babelrc
,寫入如下內容:
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "entry"
}
]
]
}
更多 babel 配置請查看babel 中文官網
配置完成后新建一個src/utils/getData.js
測試一下:
export default function getData() {
return new Promise((resolve, reject) => {
resolve('ok');
});
}
在src/App.vue
中引入:
<template>
<div class="example">
{{ msg }}
<img :src="url" />
</div>
</template>
<script>
import logo from './assets/logo.png';
import getData from './utils/getData';
export default {
data() {
return {
msg: 'Hello Vue1',
url: logo,
};
},
methods: {
async fetchData() {
const data = await getData();
this.msg = data;
},
},
created() {
this.fetchData();
},
};
</script>
<style>
.example {
color: red;
}
</style>
重新執行npm run serve
后,頁面顯示ok
,babel 引入成功
設置 src 別名以及省略后綴
為了方便開發,我們可以給 src 目錄設置別名,以及將常用文件類型的后綴省略
...
const config = {
...
// 解析路徑
resolve: {
// 設置src別名
alias: {
'@': path.resolve(__dirname, 'src'),
},
//后綴名 可以根據需要自由增減
extensions: ['.js', '.vue'],
},
...
};
...
這樣我們就可以以如下方式導入 vue 和 js 文件:
// 導入App.vue
import App from '@/App';
// 導入getData
import getData from '@/utils/getData';
至此,我們已經簡單的搭建出了 vue 項目,在項目中我們可能還會需要用到less
,sass
,字體圖標等工具,針對這類工具 webpack 都有與其對應的loader
或plugin
,需要時搜索他們的文檔即可。
- 本項目倉庫 qiyuor2/webpack-vue