前言
好了,上一篇我講了怎麼使用webpack來建構vue項目,接下将對它進一步完善,添加靜态資源和代碼校驗及webpack-dev-server伺服器,廢話不多說,直接開始吧。
配置靜态資源
安裝
在配置之前,需要安裝樣式和檔案資源處理的loader
npm install style-loader --save-dev
npm install --save-dev url-loader file-loader //url-loader是基于file-loader的
配置
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
},
{
test: /\.(gif|jpg|jpeg|png|svg)/,
use: {
loader: 'url-loader',
options: {
limit: 1024, // 每次輸出檔案的位元組數的大小
name: '[name].[ext]' // 輸出的檔案類型
}
}
}
]
},
css處理器
這裡css處理器使用的是stylus,當然也可以使用其他處理器,可以根據個人習慣去更換,我這裡使用它是因為它編寫的樣式簡潔,容易閱讀
安裝
npm install stylus-loader stylus --save-dev
配置
module: {
rules: [
{
test: /\.styl(us)?/,
use: [
'css-loader',
'stylus-loader'
]
}
]
}
安裝配置webpack-dev-server
安裝
npm install --save-dev webpack-dev-server html-webpack-plugin
npm install --save-dev cross-env
// cross-env是設定系統環境變量的,不同平台會有不同的環境變量,cross-env主要提供處理環境變量方案,隻要正确的設定,則無需在開發中過多的去關注環境變量的設定問題
cross-env的配置
cross-env是運作跨平台設定和使用環境變量的腳本
{
"scripts": {
"build": "cross-env NODE_ENV=production webpack --config build/webpack.config.js"
}
}
webpack-dev-server的配置
const webpack = require('webpack')
const isDev = process.env.NODE_ENV === 'development'
const config = {
target: 'web', // 編譯目标
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: isDev ? '"development"' : '"production"'
}
}),
new HtmlWebpackPlugin({
template: path.join(__dirname, 'template.html')
})
]
}
if (isDev) {
config.devtool = '#cheap-module-eval-source-map'
config.devServer = {
port: 8010,
host: '0.0.0.0', // 可以通過loaclhost、127.0.0.1、本機内網ip、手機等通路
overlay: { // 将編譯的錯誤顯示到頁面上
errors: true
},
hot: true // 熱加載
}
}
html-webpack-plugin參看文檔:https://www.webpackjs.com/plugins/html-webpack-plugin/
package.json 項目運作指令配置
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "cross-env NODE_ENV=production webpack --config build/webpack.config.js",
"dev": "cross-env NODE_ENV=development webpack-dev-server --config build/webpack.config.js"
},
// 運作指令
npm run dev
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHLy0keOBTVq10MNpHW4Z0MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLzUzNwUjM1EjMxEzMwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
好了,到現在我們的項目算是建構和運作成功了,下面我們就來添加校驗代碼功能,為什麼要添加代碼校驗,這裡就不多說了,添加它可以更好的去管理代碼,團隊協作
代碼校驗eslint的配置
eslint官方文檔:http://eslint.cn/docs
安裝eslint
npm install --save-dev eslint
安裝standard标準
npm install --save-dev eslint-config-standard eslint-plugin-standard eslint-plugin-promise eslint-plugin-import eslint-plugin-node
在根目錄下建立 .eslintrc 檔案,到了這裡是不是可以進行配置了呢,當然是可以的,但是eslint無法直接識别vue檔案,是以還需要安裝eslint-plugin-html
npm install --save-dev eslint-plugin-html
// 安裝eslint對vue的校驗
npm install eslint-plugin-vue --save-dev
.eslintrc檔案配置
{
"extends": ["standard", "plugin:vue/recommended"],
"plugins": [
"html"
]
}
運作eslint的指令配置(package.json)
"scripts": {
"lint": "eslint --ext .js --ext .jsx --ext .vue src/",
"lint-fix": "eslint --fix --ext .js --ext .jsx --ext .vue src/"
},
–fix自動修複問題代碼
自動校驗代碼
npm i --save-dev eslint-loader babel-eslint
在eslintrc檔案中增加如下配置
"parserOptions": {
"parser": "babel-eslint",
"ecmaFeatures": {
"jsx": true
}
為了更好使用代碼規則,避免錯誤的代碼格式送出到遠端倉庫,需要安裝husky(二哈)
npm i --save-dev husky
在package.json中的配置
"scripts": {
"lint-fix": "eslint --fix --ext .js --ext .jsx --ext .vue src/",
"precommit": "npm run lint-fix"
},
在正式開發項目功能之前還需配置postcss、babel
npm i --save-dev postcss-loader autoprefixer
npm i --save-dev babel-loader @babel/core
babel相關工具
npm i --save-dev @babel/preset-env babel-plugin-transform-vue-jsx @babel/plugin-syntax-jsx vue-eslint-parser babel-helper-vue-jsx-merge-props
postcss.config.js 配置檔案
const autoprefixer = require('autoprefixer')
module.exports = {
plugins: [
autoprefixer()
]
}
module: {
rules: [
{
test: /\.jsx$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
},
{
test: /\.styl(us)?/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
sourceMap: true
}
},
'stylus-loader'
]
}
]
}
.babelrc配置檔案
{
"presets": [
"@babel/preset-env"
],
"plugins": [
"transform-vue-jsx"
]
}
CSS樣式提取
安裝
npm i --save-dev mini-css-extract-plugin
配置
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css'
})
],
optimization: {
splitChunks: {
cacheGroups: { // 設定緩存組
commons: {
chunks: 'initial',
minChunks: 2, // 在分割子產品之前共享子產品的最小塊數(預設是1)
maxInitialRequests: 5, // 入口點上的最大并行請求數(預設是3)
minSize: 0
},
vendor: {
test: /[\\/]node_modules[\\/]/,
chunks: 'initial',
name: 'vendor',
priority: 10,
enforce: true
}
}
},
runtimeChunk: true
}
為了更好的管理webpack.config.js檔案,我将它拆分成兩個檔案webpack.config.base.js和webpack.config.client.js,在拆分前,需要安裝webpack-merge
npm i --save-dev webpack-merge
webpack.config.base.js
const path = require('path')
const config = {
entry: path.resolve(__dirname, '../src/index.js'), // 入口js檔案
output: { // webpack打包輸出js檔案的路徑及檔案名
filename: 'bundle.[hash:8].js',
path: path.resolve(__dirname, '../dist')
},
mode: process.env.NODE_ENV || 'production', // 判斷其環境
module: {
rules: [
{ // 代碼校驗
test: /\.(vue|js|jsx)$/,
loader: 'eslint-loader',
exclude: /node_modules/,
enforce: 'pre'
},
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.jsx$/,
loader: 'babel-loader'
},
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
plugins: ['@babel/transform-runtime']
}
}
},
{
test: /\.(gif|jpg|jpeg|png|svg)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 1024,
name: 'resources/[path][name].[ext]'
}
}
]
}
]
}
}
module.exports = config
webpack.config.client.js
const path = require('path')
const merge = require('webpack-merge')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const webpack = require('webpack')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const baseConfig = require('./webpack.config.base')
const isDev = process.env.NODE_ENV === 'development'
const devServer = {
port: 8010,
host: '0.0.0.0', // 可以通過loaclhost、127.0.0.1、本機内網ip、手機等通路
overlay: { // 将編譯的錯誤顯示到頁面上
errors: true
},
hot: true // 熱加載
}
const defaultPlugin = [
new VueLoaderPlugin(),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: isDev ? '"development"' : '"production"'
}
}),
new HtmlWebpackPlugin({
template: path.join(__dirname, 'template.html')
})
]
let config
if (isDev) {
config = merge(baseConfig, {
devtool: '#cheap-module-eval-source-map',
module: {
rules: [
{
test: /\.styl(us)?/,
use: [
'vue-style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
sourceMap: true
}
},
'stylus-loader'
]
}
]
},
devServer,
plugins: defaultPlugin.concat([
new MiniCssExtractPlugin({
filename: '[name].[chunkHash:8].css',
chunkFilename: '[name].[chunkHash:8].css'
})
])
})
} else {
config = merge(baseConfig, {
module: {
rules: [
{
test: /\.styl(us)?/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader',
options: {
sourceMap: true
}
},
'stylus-loader'
]
}
]
},
plugins: defaultPlugin.concat([
new MiniCssExtractPlugin({
filename: '[name].[chunkHash:8].css',
chunkFilename: '[name].[chunkHash:8].css'
})
]),
optimization: {
splitChunks: {
cacheGroups: { // 設定緩存組
commons: {
chunks: 'initial',
minChunks: 2, // 在分割子產品之前共享子產品的最小塊數(預設是1)
maxInitialRequests: 5, // 入口點上的最大并行請求數(預設是3)
minSize: 0
},
vendor: {
test: /[\\/]node_modules[\\/]/,
chunks: 'initial',
name: 'vendor',
priority: 10,
enforce: true
}
}
},
runtimeChunk: true
}
})
}
module.exports = config
最後安裝兩個有趣的工具pre-commit 和 rimraf
// pre-commit 預送出,簡單的說就是送出到git的時候提前執行一遍
npm install --save-dev pre-commit
// 用于删除dist目錄
npm install --save-dev rimraf
在package.json中配置如下
"scripts": {
"precommit": "npm run lint-fix",
"clean": "rimraf dist"
},
pre-commit圖: