本文從零開始vu2+webpack4腳手架搭建,各類步驟配置均可從最後的「參考」中得到,採用yarn做爲包管理工具,mac系統,vs code做爲ide開發工具。舒適提示:全部命令執行都是在項目目錄(vue-demo)中執行。根據本教程走一遍(記得看參考中對應的鏈接),webpack4的經常使用插件、加載器基本熟悉,可應付大部分開發。css
`mkdir vue-demo && cd vue-demo && yarn init`
複製代碼
yarn add webpack webpack-cli -D
html
配置webpack編譯腳本 vi package.json 新增以下內容:vue
"scripts": {
"build": "webpack --config webpack.config.js"
},
複製代碼
touch webpack.config.js && vi webpack.config.js
// 配置入口文件與輸出打包文件及路徑
const path = require('path')
module.exports = {
entry: './src/index.js',
output: {
path: path.join(__dirname, dist),
filename: 'index.js'
}
}
複製代碼
建立入口文件 ./src/index.js: mkdir src && touch ./src/index.js
node
console.log('Hello vue2&webpack4.')
複製代碼
測試配置 yarn build && node ./dist/bundle.js
驗證dist/bundle.js是否存在,控制檯輸出"Hello vue2&webpack4."字符串即表示成功webpack
添加html-webpack-plugin yarn add html-webpack-plugin -D
git
修改webpack.config.js配置github
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
mode: "development",
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
plugins:[
new HtmlWebpackPlugin({
title: 'Vue2 && Webpack4'
})
]
}
複製代碼
yarn build
編譯驗證,採用瀏覽器打開dist/index.html,cmd+option+i查看控制檯輸出"Hello vue2&webpack4."字符串web
yarn add vue
npm
yarn add vue-loader vue-template-compiler css-loader -D
json
yarn add url-loader file-loader -D
修改webpack.config.js配置
const path = require('path')
const { VueLoaderPlugin } = require('vue-loader')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const config = {
mode: 'development',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
plugins:[
new VueLoaderPlugin(),
new HtmlWebpackPlugin({
title: 'Vue2 && Webpack4'
})
],
// 新增vue-loader配置
module:{
rules: [
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.css$/,
use: ['vue-style-loader', 'css-loader'],
},
{
test: /\.(png|jpe?g|gif)$/i,
use: [
{
loader: 'url-loader',
options: {
// 自定義輸出命名規則
name: 'resources/[name].[hash:8].[ext]',
// 圖片轉爲base64的最大閾值
limit: 8192,
// 當大於limit時採用file-loader加載器處理,默認便是file-loader
fallback: 'file-loader'
}
}
]
}
]
}
}
module.exports = config
複製代碼
建立源碼存放目錄mkdir src/components && mkdir src/api && mkdir src/store && mkdir -p src/assets/images
,拷貝2張圖片到src/assets/images目錄下,分別命名以下:bg.jpg logo.png,最好有一張大於8092kb(見上配置)
建立src/components/app.vue
<template>
<div>
<h2>{{title}}</h2>
<img src="../assets/images/logo.png" width="50px" height="50px"/>
<div class="bg">
我在背景圖上
</div>
</div>
</template>
<script>
export default {
data() {
return {
title: 'Hello vue2&&webpack4....3'
}
}
}
</script>
<style scoped>
.bg {
width: 500px;
height: 500px;
background-image: url('../assets/images/bg.jpg');
}
</style>
複製代碼
編譯yarn build
瀏覽器打開dist/index.html能夠到展現Hello vue2&&webpack4. logo圖以及背景圖
`yarn add -D postcss-loader autoprefixer`
複製代碼
{
test: /\.css$/,
exclude: /node_modules/,
// 舒適提示:webpack調用順序是從右到左
use: ['vue-style-loader', 'css-loader', 'postcss-loader']
},
複製代碼
module.exports = {
plugins: [
// require('precss'),
require('autoprefixer')
]
複製代碼
}
3. 修改src/components/app.vue
複製代碼
我就測試一下,看看而已
test-prefix[data-v-6c0a0fc1]{\\n display: flex;\\n
-webkit-user-select: none;\\n -moz-user-select: none;\\n
-ms-user-select: none;\\n user-select: none;\\n}\\n\", \"\"] 複製代碼
yarn add mini-css-extract-plugin --save-dev
// 新增
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
// 修改
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,//devMode ? 'vue-style-loader' : MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader'
],
},
// {
// test: /\.css$/,
// exclude: /node_modules/,
// // 舒適提示:webpack調用順序是從右到左
// use: ['vue-style-loader', 'css-loader', 'postcss-loader'],
// },
// 新增
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: '[name].css',//devMode ? '[name].css' : '[name].[hash].css',
chunkFilename: '[id].css'// devMode ? '[id].css' : '[id].[hash].css',
})
複製代碼
yarn build
,查看dist目錄下生成的main.css文件,內容以下:.bg[data-v-6c0a0fc1] {
width: 500px;
height: 200px;
background-image: url(resources/bg.dedfb384.jpg);
}
/* 新增 */
.test-prefix[data-v-6c0a0fc1]{
display: flex;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
color: red;
}
複製代碼
dist/bundle.js搜索test-prefix,只能看到引用而沒有此類定義,即被提取到main.css文件yarn add babel-loader @babel/core @babel/preset-env webpack -D
yarn add @babel/polyfill
修改webpack配置
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
// 配置也可獨立到.babelrc文件中
options: {
presets: ['@babel/preset-env']
}
}
},
複製代碼
修改src/components/app.vue
<template>
<div>
<h2>{{title}}</h2>
<!-- 新增 -->
<div class="test-prefix">
<p>我就測試一下,看看而已,我是紅色哦</p>
</div>
<img src="../assets/images/logo.png" width="50px" height="50px"/>
<div class="bg">
我在背景圖上
<div v-for="(item, index) in list" :key="index">
{{item}}
</div>
</div>
<button @click="onClickButton">測試ES6 ES7語法</button>
</div>
</template>
<script>
require('@babel/polyfill')
class Echo {
constructor(msg){
this.msg = msg
}
print() {
console.log(this.msg)
}
getMsg() {
return this.msg
}
}
export default {
data() {
return {
title: 'Hello vue2&&webpack4....3',
list: ['test1', 'test2', 'test3']
}
},
methods: {
onClickButton(e) {
let echo = new Echo('我是ES6語法class構建的對象哦')
echo.print();
alert(echo.getMsg())
let sum = 2 ** 10
alert(`ES7 求冪運算符(2 ** 10)= ${sum}`)
},
// async特性,切記添加require('@babel/polyfill')在前面
async getA() {
return new Promise((resolve, rejuect) => {
console.log('====== getA')
setTimeout(()=>resolve(`It's timeout.`), 3000) }) } } } </script> <style scoped> .bg { width: 500px; height: 200px; background-image: url('../assets/images/bg.jpg'); } /* 新增 */ .test-prefix{ display: flex; user-select: none; color: red; } </style> 複製代碼
yarn build
,打開dist/bundle.js文件,搜索onClickButton,可看到函數體裏面的求冪運算**被轉爲了Math.pow函數,如:onClickButton:function(t){var e=new s("我是ES6語法class構建的對象哦");e.print(),alert(e.getMsg());var n=Math.pow(2,10);alert("求冪運算符(2 ** 10)= ".concat(n))}
複製代碼
yarn add -D eslint eslint-plugin-vue
yarn add -D eslint-config-standard eslint-plugin-standard eslint-plugin-promise eslint-plugin-import eslint-plugin-node
module.exports = {
extends: [
// add more generic rulesets here, such as:
// 'eslint:recommended',
// 'plugin:vue/recommended',
"plugin:vue/essential"
],
rules: {
// override/add rules settings here, such as:
// 'vue/no-unused-vars': 'error'
'no-console': 'off',
},
"plugins": [
]
}
複製代碼
<template>
<div>
<h2>{{ title }}</h2>
<div class="test-prefix">
<p>我就測試一下,看看而已,我是紅色哦</p>
</div>
<img
src="../assets/images/logo.png"
width="50px"
height="50px"
/>
<div class="bg">
我在背景圖上
</div>
<button v-bind:click="onClickButton">
測試ES6語法
</button>
<!-- idx沒使用,給eslint-plugin-vue檢測 -->
<div v-for="(item, idx) in list" :key="item.id">
<p>{{item}}{{}}</p>
</div>
</div>
</template>
<script>
class Echo {
constructor (msg) {
this.msg = msg
}
print () {
console.log(this.msg)
}
getMsg () {
return this.msg
}
}
export default {
data () {
return {
title: 'Hello vue2&&webpack4....3',
list: ['test1', 'test2', 'test3']
}
},
methods: {
onClickButton (e) {
// js標準風格字符串必須適應'號,故意爲之 let echo = new Echo("我是ES6語法class構建的對象哦") echo.print() alert(echo.getMsg()) let sum = 2 ** 10 alert(`求冪運算符(2 ** 10)= ${sum}`) } } } </script> <style scoped> .bg { width: 500px; height: 200px; background-image: url('../assets/images/bg.jpg'); } /* 新增 */ .test-prefix{ display: flex; user-select: none; color: red; } </style> 複製代碼
"lint": "eslint src/**/*.{js,vue}",
yarn lint
,能夠看到輸出2處錯誤都是src/components/App.vue中引發的,根據報錯緣由修改後,再運行正常便可。舒適提示:可安裝ide插件自動提示修復eslint錯誤。yarn add clean-webpack-plugin --save-dev
修改webpack.config.js配置
// 引入插件
const CleanWebpackPlugin = require('clean-webpack-plugin')
// 修改
plugins:[
new VueLoaderPlugin(),
new HtmlWebpackPlugin({
title: 'Vue2 && Webpack4',
// template: './src/index.html'
}),
// 新增
new CleanWebpackPlugin([
'dist'
], {
// Absolute path to your webpack root folder (paths appended to this)
// Default: root of your package
root: __dirname,
exclude: [],
// Write logs to console.
verbose: true,
// Use boolean "true" to test/emulate delete. (will not remove files).
// Default: false - remove files
dry: false,
// If true, remove files on recompile.
// Default: false
watch: false,
})
],
複製代碼
驗證,yarn build
,可先看到刪除dist目錄而後再生成dist目錄內容
yarn add eslint-loader
修改webpack配置
{
enforce: "pre",
test: /\.(vue|js)$/,
exclude: /node_modules/,
loader: "eslint-loader"
}
複製代碼
不修復步驟十執行yarn lint
出錯的代碼,執行yarn build
會出現一樣的錯誤build前進行了eslint檢測,根據錯誤緣由修復後再執行便可正常打包。
mkdir build && mv webpack.config.js build/webpack.config.js && touch build/webpack.config.dev.js && touch build/webpack.config.prod.js
yarn add -D webpack-merge
抽離公共邏輯在webpack.config.js,開發特性配置放在build/webpack.config.dev.js,生產特性配置放在build/webpack.config.dev.js
修改三文件內容以下:
// build/webpack.config.js
const path = require('path')
const { VueLoaderPlugin } = require('vue-loader')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CleanWebpackPlugin = require('clean-webpack-plugin')
const config = {
entry: path.resolve(__dirname, '../src/index.js'), // 爲消除異議,明確指定
//entry: './src/index.js',// 相對路徑這裏不是基於本文件的位置,而是工程目錄,因此不是../src/index.js
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
plugins:[
new VueLoaderPlugin(),
new HtmlWebpackPlugin({
title: 'Vue2 && Webpack4',
// template: './src/index.html'
}),
new CleanWebpackPlugin([
path.resolve(__dirname, 'dist')
], {
// Absolute path to your webpack root folder (paths appended to this)
// Default: root of your package
root: __dirname,
exclude: [],
// Write logs to console.
verbose: true,
// Use boolean "true" to test/emulate delete. (will not remove files).
// Default: false - remove files
dry: false,
// If true, remove files on recompile.
// Default: false
watch: false,
})
],
// 新增vue-loader配置
module:{
rules: [
{
enforce: "pre",
test: /\.(vue|js)$/,
exclude: /node_modules/,
loader: "eslint-loader"
},
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
// 配置也可獨立到.babelrc文件中
options: {
presets: ['@babel/preset-env']
}
}
},
{
test: /\.vue$/,
loader: 'vue-loader'
},
// {
// test: /\.css$/,
// exclude: /node_modules/,
// // 舒適提示:webpack調用順序是從右到左
// use: ['vue-style-loader', 'css-loader', 'postcss-loader'],
// },
{
test: /\.(png|jpe?g|gif)$/i,
use: [
{
loader: 'url-loader',
options: {
// 自定義輸出命名規則
name: 'resources/[name].[hash:8].[ext]',
// 圖片轉爲base64的最大閾值
limit: 8192,
// 當大於limit時採用file-loader加載器處理,默認便是file-loader
fallback: 'file-loader'
}
}
]
}
]
},
// webpack will automatically split chunks based on these conditions:
// New chunk can be shared OR modules are from the node_modules folder
// New chunk would be bigger than 30kb (before min+gz)
// Maximum number of parallel requests when loading chunks on demand would be lower or equal to 5
// Maximum number of parallel requests at initial page load would be lower or equal to 3
// When trying to fulfill the last two conditions, bigger chunks are preferred.
// 默認配置
optimization: {
splitChunks: {
chunks: 'async',
minSize: 30000,
maxSize: 0,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
}
}
module.exports = config
複製代碼
// build/webpack.config.dev.js
const baseConfig = require('./webpack.config.js')
const webpackMerge = require('webpack-merge')
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
const config = webpackMerge.smart(baseConfig, {
mode: 'development',
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: '[name].css',//devMode ? '[name].css' : '[name].[hash].css',
chunkFilename: '[id].css'// devMode ? '[id].css' : '[id].[hash].css',
})
],
module:{
rules: [
{
test: /\.css$/,
use: [
'vue-style-loader',//devMode ? 'vue-style-loader' : MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader'
],
},
]
}
})
module.exports = config
複製代碼
// build/webpack.config.js
const baseConfig = require('./webpack.config.js')
const webpackMerge = require('webpack-merge')
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
const config = webpackMerge.smart(baseConfig, {
mode: 'production',
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: '[name].[hash].css',
chunkFilename: '[id].[hash].css',
})
],
module:{
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,//devMode ? 'vue-style-loader' : MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader'
],
},
]
}
})
module.exports = config
複製代碼
// 修改package.json
"scripts": {
"lint": "eslint src/**/*.{js,vue}",
"build": "yarn build:prod",
"build:prod": "webpack --config ./build/webpack.config.prod.js",
"build:dev": "webpack --config ./build/webpack.config.dev.js"
},
複製代碼
驗證,yarn build:prod
打包生產環境,yarn build:dev
打包開發環境,可對比兩次打包build/dist下生成的內容
開發環境配置服務,以及熱更新
yarn add -D webpack-dev-server
修改build/webpack.config.dev.js
devServer: {
open: true,
contentBase: path.resolve(__dirname, 'dist'),
compress: false,
port: 9000,
hot: true
},
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: '[name].css',//devMode ? '[name].css' : '[name].[hash].css',
chunkFilename: '[id].css'// devMode ? '[id].css' : '[id].[hash].css',
}),
new webpack.HotModuleReplacementPlugin()
],
複製代碼
修改package.json
"scripts": {
"lint": "eslint src/**/*.{js,vue}",
"build": "yarn build:prod",
"build:prod": "webpack --config ./build/webpack.config.prod.js",
"build:dev": "webpack --config ./build/webpack.config.dev.js",
"start": "webpack-dev-server --progress --config ./build/webpack.config.dev.js"
},
複製代碼
驗證:yarn start
, 成功後自動利用默認瀏覽器打開build/dist/index.html,修改src/components/App.vue的樣式或內容,保存即會自動打包同步到打開頁面。
本文主要根據各個需求點的官網指導例子進行編寫,基本無錯進行到底。因此文檔仍是一手的好。本文demo已上傳到git。歡迎交流start。
複製代碼