針對新手入門搭建專案,Webpack5 配置手冊(從0開始)
webpack安裝順序
1. `npm init -y`,初始化包管理檔案 package.json
2. 新建src原始碼目錄
3. 新建index.html
4. `yarn add webpack webpack-cli`,安裝webpack相關包
5. 在專案根目錄中,建立webpack.config.js 的配置檔案
6. `yarn add webpack-dev-server`,安裝支援專案自動打包的工具,並配置
7. `yarn add html-webpack-plugin`,安裝生成預覽頁面外掛並配置
8. `yarn add style-loader css-loader`,安裝處理css檔案的loader
9. `yarn add less-loader less`,安裝處理less檔案的loader
10. `yarn add sass-loader node-sass`,安裝處理scss檔案的loader
11. `yarn add postcss postcss-loader postcss-preset-env autoprefixer`,配置postCSS自動新增css的相容字首(可選)
12. `yarn add url-loader file-loader`,安裝處理css檔案中的圖片和字型檔案
13. `yarn add html-loader`,安裝處理html檔案中的圖片和字型檔案
14. `yarn add @babel/core babel-loader @babel/preset-env 前面3個是必須的,後面的看需要 @babel/plugin-transform-runtime @babel/plugin-proposal-class-properties`,安裝處理js高階語法(ES6以上)
15. 之後看下面的外掛安裝程式碼。
yarn add html-webpack-plugin
yarn add style-loader css-loader
yarn add less-loader less
yarn add sass-loader node-sass
yarn add url-loader file-loader
yarn add html-loader
yarn add @babel/core babel-loader @babel/preset-env 前面3個是必須的,後面的看需要 @babel/plugin-transform-runtime @babel/plugin-proposal-class-properties
yarn add postcss postcss-loader postcss-preset-env
yarn add mini-css-extract-plugin
yarn add optimize-css-assets-webpack-plugin
yarn add eslint eslint-loader eslint-webpack-plugin
yarn add eslint-config-airbnb-base 或 eslint-config-airbnb 或 vue的eslint
yarn add clean-webpack-plugin
使用npx babel-upgrade
將所有關於babel的外掛都升級都最新版本以適應相容性
在.babelrc 中配置,或者在package.json中直接新增
{
"presets": ["@babel/preset-env"],
"plugins": [
"@babel/plugin-transform-runtime",
"@babel/plugin-proposal-class-properties"
]
}
webpack.config.js中配置外掛
const path = require('path');
const htmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
mode: 'development',
entry: path.join(__dirname, './src/main.js'),
output: {
path: path.join(__dirname, './dist'),
filename: 'bundle.js',
},
// 外掛
plugins: [
// html
new htmlWebpackPlugin({
template: path.join(__dirname, './src/index.html'),
filename: 'index.html',
}),
// 打包前清除dist
new CleanWebpackPlugin(),
],
// Loaders 部分
module: {
rules: [
{
// test設定需要匹配的檔案型別,支援正則
test: /\.css$/,
// use表示該檔案型別需要呼叫的loader
use: ['style-loader', 'css-loader'],
},
{
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader'],
},
{
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader'],
},
{
test: /\.(png|gif|bmp|jpg)$/,
use: {
loader: 'url-loader',
options: {
limit: 8 * 1024,
// 圖片取10位hash和副檔名
name: '[hash:10].[ext]',
// 關閉es6模組化
esModule: false,
// 圖片資源的輸出路徑
outputPath: 'images',
},
},
},
// 處理html中img資源
{
test: /.\html$/,
loader: "html-loader"
},
// 處理其他資源(一般指的就是字型資源等)
// {
// exclude: /\.(html|js|css|less|scss|jpg|png|gif)/,
// loader: "file-loader",
// outputPath:'media'
// },
{
test: /\.(woff(2)?|eot|ttf|otf|svg|)$/,
type: 'asset/inline',
},
{
test: /\.js/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
plugins: ['@babel/plugin-proposal-class-properties'],
},
},
},
],
},
// 使用webpck-dev-server時配置
devServer: {
historyApiFallback: true,
contentBase: path.join(__dirname, './dist'),
open: true,
hot: true,
quiet: true,
port: 3000,
},
};
webpack.config.js中配置外掛
const { resolve } = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ESLintPlugin = require('eslint-webpack-plugin');
// 匯入每次刪除資料夾的外掛
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
// 複用loader載入器
const commonCssLoader = [
MiniCssExtractPlugin.loader,
'css-loader',
// css相容性處理
// 還需要在package.json中定義browserlist
'postcss-loader'
// 下面是根據路徑找配置檔案
// {
// loader: 'postcss-loader',
// options: {
// postcssOptions:{
// config:'./postcss.config.js'
// }
// }
// }
];
// 定義node.js到環境變數,決定使用browserslist的哪個環境
process.env.NODE_ENV = 'production';
module.exports = {
entry: './src/main.js',
output: {
filename: 'js/bundle.js',
path: resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.css$/,
use: [
...commonCssLoader,
]
},
{
test: /\.less$/,
use: [
...commonCssLoader,
'less-loader'
]
},
// {
// // eslint語法檢查,在package.json中eslintConfig --> airbnb的校驗規則
// test: /\.js$/,
// exclude: /node_modules/,
// // 優先執行,先執行eslint在執行babel
// enforce: 'pre',
// loader: 'eslint-loader',
// options: {
// fix: true
// }
// },
{
// js程式碼相容性處理
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-env', //基礎預設
{
useBuiltIns: 'usage', // 按需載入
corejs: {
version: 3
},
targets: {
// 相容到什麼版本到瀏覽器
chrome: '60',
firefox: '50',
ie: '9',
safari: '10',
edge: '17'
}
}
]],
plugins: ['@babel/transform-runtime','@babel/plugin-proposal-class-properties'],
}
},
{
test: /\.(png|gif|bmp|jpg)$/,
use: {
loader: 'url-loader',
options: {
limit: 8 * 1024,
// 圖片取10位hash和副檔名
name: '[hash:10].[ext]',
// 關閉es6模組化
esModule: false,
// 圖片資源的輸出路徑
outputPath: 'images',
// publicPath : 這個則是生成的頁面中對圖片路徑的引用時,加上publicPath。
publicPath: "../images"
}
}
},
// 處理html中img資源
{
test: /.\html$/,
loader: 'html-loader'
},
// 處理其他⽂件
{
exclude: /\.(js|css|less|html|jpg|png|gif)/,
loader: 'file-loader',
options: { outputPath: 'media', },
},
]
},
plugins: [
// css程式碼單獨抽離
new MiniCssExtractPlugin({
filename: 'css/bundle.css'
}),
// css程式碼壓縮
new OptimizeCssAssetsWebpackPlugin(),
// html檔案壓縮
new HtmlWebpackPlugin({
template: './src/index.html',
minify: {
// 移除空格
collapseWhitespace: true,
// 移除註釋
removeComments: true
}
}),
// new ESLintPlugin({
// exclude:'node_modules',
// fix:true
// }),
new CleanWebpackPlugin(),
]
,
mode: 'production'
};
postcss.config.js配置
module.exports = {
// You can specify any options from https://postcss.org/api/#processoptions here
// parser: 'sugarss',
plugins: [
// Plugins for PostCSS
// ["postcss-short", { prefix: "x" }],
"postcss-preset-env",
],
};
.eslintlrc.js配置
module.exports = {
root: true,
env: {
commonjs: true,
es6: true,
browser: true,
node: true
},
extends: [
"airbnb-base",
// 'plugin:vue/essential',
// '@vue/standard'
],
parserOptions: {
ecmaVersion: 7,
ecmaFeatures: {
jsx: true,
experimentalObjectRestSpread: true,
},
parser: 'babel-eslint',
sourceType: "module"
},
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
}
}
.gitignore配置
node_modules/*
package-lock.json
dist/*
.idea/*
package.json配置
{
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"serve": "webpack serve",
"dev": "webpack --config webpack.config.js",
"build": "webpack --config webpack.pub.config.js"
},
"browserslist": {
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
"production": [
">0.2%",
"not dead",
"not op_mini all"
]
}
}
遇到的問題
- 開發環境,熱部署devServer的重新配置,在webpack.config.js中新增熱部署的部分程式碼,之後在package.json
檔案內scripts中配置相應的webpack - 生產環境在package.json中的配置
"build": "webpack --config webpack.pub.config.js"
- 生產環境圖片資源打包之後,網頁顯示不出來,需要在圖片資源的打包中新增
publicPath: "../images"
,這個
則是生成的頁面中對圖片路徑的引用時,加上publicPath,這樣訪問時姐可以放到檔案的正確地址了。 - css程式碼的相容性處理,使用postcss-loader的配置,可以直接在use里載入postcss-loader的配置檔案,也可以直接
使用postcss-loader,讓後打包時自動在根目錄中找postcss.confgi.js配置檔案,來載入postcss配置,此專案使用的
外部postcss.confgi.js配置檔案的配置方式。注意:還需要在package.json中定義browserlist - 另外:目前還有生產環境懶載入和eslint校驗程式碼的功能未完成,eslint的校驗遇到問題
class Person { static info = { name: 'zs' }; }
,在生產環境的webpack.pub.config.js中引入來外掛eslint-webpack-plugin,配置了new ESLintPlugin(),
但是提示錯誤資訊如下,Parsing error: Unexpected token =