基於Webpack4的Vue移動端開發環境-搭建篇

寫在前面

在使用Vue開發單頁面的時候,咱們大多數時候都是使用的官方CLI工具,如今的Vue CLI已經迭代到了4.X了,能夠說很成熟穩定了,能知足大多數要求,並且上手簡單。本着折騰摸索的精神,仍是打算本身搭建一個開發環境,熟悉各個流程。css

本文不涉及Webpack和babel知識的講解,建議瞭解一下Webpack的基本知識來看這篇文章會更好理解。這個在網上能找到不少教程。關於node.js和npm安裝在這裏也再也不贅述,相信作前端開發這個是電腦必備的。html

若是你在搭建過程當中遇到不明的報錯,查看報錯信息並記錄排查,有時候相關的插件在更新事後使用方式會發生變化,有可能你按着個人配置走下來也報錯,那麼看看官方文檔(通常在github上查相關的倉庫便可)有沒有改變寫法,好比此次我配置的clean-webpack-plugin插件,之前的版本是不須要解構的,可是如今必須解構了,否則它會報錯並提示不是構造函數前端

大佬繞路輕噴。。。vue

更新:若是開發環境和生產環境都使用插件把CSS分離出來成爲單獨的文件,那麼你在開發過程當中會發現熱更新對CSS不生效,因此解決方法就是分離CSS僅配置在生產環境。給你們埋了個坑,sorry!node

優化篇已經出爐:基於Webpack4的Vue移動端開發環境-優化篇webpack

個人node.js及npm版本以下:css3

node -v
v12.13.0

npm -v
v6.12.0
複製代碼

開始

一、初始化一個項目

首先你要新建一個文件夾,我這兒叫 customized-vue-proj-mobile,而後在你的文件夾右鍵打開git bash輸入如下命令來初始化項目(須要安裝git,固然用cmd也是能夠的):git

npm init
複製代碼

執行完這個命令事後,會在目錄生成一個 package.json 的文件,個人文件內容以下:es6

{
  "name": "customized-vue-proj-mobile",
  "version": "1.0.0",
  "description": "customized vue development environment",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/cookiepool/customized-vue-proj-mobile.git"
  },
  "keywords": [
    "vue",
    "mobile"
  ],
  "author": "LEE",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/cookiepool/customized-vue-proj-mobile/issues"
  },
  "homepage": "https://github.com/cookiepool/customized-vue-proj-mobile#readme"
}
複製代碼

這兒關於npm包管理也有不少知識點,這裏不在展開,建議你們能夠自行了解下github

這樣一個項目就先初始化完畢,接下來開始進入各類工具的安裝來完成環境的搭建。

二、安裝webpack

基於webpack的話確定要先安裝好webpack才能繼續安裝後續的,因此先來安裝命令:

npm install webpack --save-dev
複製代碼
  • --save-dev 表示將包安裝信息放入到 package.jsondevDependencies 裏面,這個不會用於生產環境,-D 等效於 --save-dev
  • --save 表示將包安裝信息放入到 package.jsondependencies 裏面,這個會打包用於生產環境。-S 等效於 --save

接下來還須要安裝CLI,從webpack4開始必需要安裝webpack cli才能執行webpack相關的命令

npm install webpack-cli -D
複製代碼

接下來輸入 npx webpack --help 來測試webpack是否處於可用狀態,若是輸入這個命令後面板出現一大串配置幫助信息則表明webpack可用。

npx 能夠直接調用項目內部安裝的模塊,而不須要全局安裝npm模塊,若是上面的命令你不使用npx你會發現系統顯示 bash: webpack: command not found


如今在項目目錄下新建一個src文件夾,裏面新建一個main.js文件,在裏面先隨便寫點js代碼。而後在創建一個build文件夾,並新建一個webpack.config.js配置文件。這樣一來咱們的目錄結構就是這個樣子:

1.png

文件建好了可是尚未內容,確定跑不起來,接下來對webpack.config.js操做一番,這裏我不敘述具體過程了(#滑稽保命),直接貼代碼,裏面我寫了註釋:

// build/webpack.config.js
// node.js裏面自帶的操做路徑的模塊
const path = require('path');

module.exports = {
  // 指定模式,這兒有none production development三個參數可選
  // 具體做用請查閱官方文檔
  mode: 'development',
  // webpack打包的入口文件
  entry: {
    main: path.resolve(__dirname, '../src/main.js')
  },
  // webpack打包的輸出相關的額配置
  output: {
    // 打包事後的文件的輸出的路徑
    path: path.resolve(__dirname, '../dist'),
    // 打包後生成的js文件,帶hash值來保證文件的惟一性
    filename: 'js/[name].[hash:4].js',
    // 生成的chunk文件名
    chunkFilename: 'js/[name].[hash:4].js',
    // 資源的引用路徑(這個跟你打包上線的配置有關係)
    publicPath: '/'
  }
}
複製代碼

而後呢再把package.json改造一下,在scripts處添加一句 dev 這個命令:

"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "dev": "webpack ./src/main.js --config ./build/webpack.config.js"
},
複製代碼

一頓操做事後,咱們開始來試一試這個命令能不能用,在控制檯下輸入:

npm run dev
複製代碼

稍等一下子就會出現如下信息,則表明咱們打包輸出成功:

2.png

此時項目的結構變成這個樣子:

3.png

環境搭建到這兒只能說webpack配置正常了,還有許多額外東西須要配置,好比如下

  • babel,這個能夠把ES6+轉換爲低瀏覽器可用的ES5,以及對一些新API作polyfill處理
  • css預處理器,目前css預處理器有不少選擇,這裏我選擇了scss來作配置,固然你不使用css預處理器也是能夠的。
  • 文件處理loader,這個主要是項目相關的圖片、字體、音視頻的處理。
  • html文件自動建立,你打包好的js文件等須要正確的導入html才能正常使用。
  • postcss,這個工具主要是處理css的,安裝相關的插件能夠實現一些功能,好比自動添加css3的前綴,移動開發中用到的px-to-rem或者px-to-vw等等。
  • 熱更新功能,在開發過程當中自動響應咱們的修改並更新,不須要手動刷新。
  • 識別.vue文件,這個是讓webpack識別.vue文件並轉換成瀏覽器能使用的內容。
  • 集成vue-router和vuex,作單頁面路由不可少,狀態管理根據須要來引入便可,不是必需要配置的東西。

三、配置相關工具

3.一、ES6+轉ES5

首先來一波安裝命令,安裝好相關的依賴:

npm install babel-loader @babel-core @babel/preset-env -D
複製代碼
  • bable-loader 這個是用於webpack來處理babel的加載器,用於調用@babel/core的核心API來完成編譯。
  • @babel-core babel的核心,核心的api都在包含在這裏。
  • @babel/preset-env babel的一個預置環境。

參考我這篇文章來瞭解一下babel,固然社區上還有許多大佬寫的文章,多看幾篇能夠了解的更加透徹。

  • 修改webpack.config.js

如今咱們須要配置webpack來使其支持babel,這裏就須要使用到剛纔安裝的babel-loader。在配置文件中加入如下代碼:

module: {
  rules: [
    {
      test: /\.jsx?$/,
      exclude: /node_modules/,
      use: [
        {
          loader: 'babel-loader'
        }	
      ]
    }
  ]
}
複製代碼
  • 在項目的根目錄新建babel.config.js

在文件中加入如下內容:

// babel.config.js
module.exports = {
  // 配置預置環境
  presets: [
    // 使用的規則
    "@babel/preset-env"
  ]
}
複製代碼

配置好後,去main.js裏面寫一些es6+的語法的js代碼,而後執行 npm run dev 你會發現dist目錄下生成的js文件語法都轉換成es5的了,可是promise卻沒有轉換,這裏咱們還須要polyfill。

  • 配置polyfill而且按需引入

輸入如下命令安裝必須的依賴:

npm install core-js@2 -S
複製代碼

安裝完畢後去babel.config.js修改代碼以下:

module.exports = {
  // 配置預置環境
  presets: [
    // 使用的規則
    ["@babel/preset-env", {
      // 這兒有false, entry, usage三個可選參數,usage能夠按需引入polyfill
      "useBuiltIns": "usage",
      // 指定corejs版本
      "corejs": 2
    }]
  ]
}
複製代碼

這樣一來你的js就能夠運行在低版本瀏覽器裏面了,好比Promise。

3.二、配置css預處理器

仍是先安裝依賴

npm install sass-loader dart-sass css-loader style-loader -D
複製代碼
  • style-loader 該loader主要是把css解析到html的style標籤上。
  • css-loader 該loader用來解析css,注意在調用style-loader和css-loader時,css-loader要先於style-loader執行,否則會報錯,當你使用如下寫法時:
use: [{loader: 'style-loader'}, {loader: 'css-loader'}]
複製代碼

由於loader加載是從右往左加載。(爲何從右往左加載 )這裏的編譯順序是先用css-loader將css代碼編譯,再交給style-loader插入到網頁裏面去。因此css-loader在右,style-loader在左。

  • sass-loader 該loader把scss或sass轉換爲css。
  • dart-sass 這個工具相似於編譯器,轉換scss語法,結合到sass-loader使用,其實還有個node-sass可使用。使用node-sass的話能夠不用在webpack的配置文件裏面指定,只須要用npm安裝好node-sass便可,這兒我使用了dart-sass因此要在implementation中指定。

下載安裝好依賴事後,在配置文件 webpack.config.js 中的 module->rules 裏面加入如下代碼:

{
  test: /\.(scss|sass)$/,
  use: [
    {
      loader: 'style-loader',
    },
    {
      loader: 'css-loader',
    },
    {
      loader: 'sass-loader',
      options: {
        implementation: require('dart-sass')
      }
    }
  ]
}
複製代碼

3.三、建立Html文件以及相關處理

首先在項目目錄建立一個目錄public,裏面再建立一個index.html,做爲單頁面的惟一入口。代碼以下:

<!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>customized-vue-proj-mobile</title>
</head>
<body>
  <div id="app"></div>
</body>
</html>
複製代碼

此時目錄結構變成如圖所示

4.png

建立好文件後咱們須要一個插件來處理html文件,只有js文件正常導入到html文件咱們的項目才能運行起來,輸入如下命令來安裝 html-webpack-plugin

npm install html-webpack-plugin -D
複製代碼

安裝完成後,再webpack配置文件的plugins中加入如下代碼:

plugins: [
  new htmlWebpackPlugin({
    // 指定模板
    template: path.resolve(__dirname, '../public/index.html'),
    // 輸出的文件
    filename: path.resolve(__dirname, '../dist/index.html')
  })
]
複製代碼

3.四、配置字體、圖片等文件的處理

開發過程確定會遇到不少媒體文件,特別是圖片,webapck有專門的loader來處理這些文件,先安裝好依賴:

npm install url-loader file-loader -D
複製代碼
  • url-loader和file-loader,這兩個其實功能差很少,url-loader的好處就是當文件小於咱們指定的大小時,它能夠把媒體文件轉換成base64編碼,這樣能夠減小項目的圖片請求,提升訪問速度。

而後咱們在webpack的配置文件中加入如下代碼:

{
  test: /\.(jpe?g|png|gif)$/i,
  use: [
    {
      loader: 'url-loader',
      options: {
        // 當文件大於5kb時走file-loader相關的配置
        limit: 5120,
        // 這個參數要設置成false,否則生成圖片的路徑時[object Module]
        esModule: false,
        // 當文件大於5kb時走file-loader相關的配置
        fallback: 'file-loader',
        // 生成的路徑和文件名
        name: 'images/[name].[hash:4].[ext]'
      }
    }
  ]
},
{
  test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
  use: [
    {
      loader: 'url-loader',
      options: {
        limit: 5120,
        esModule: false,
        fallback: 'file-loader',
        name: 'media/[name].[hash:4].[ext]'
      }
    }
  ]
},
{
  test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/i,
  use: [
    {
      loader: 'url-loader',
      options: {
        limit: 5120,
        esModule: false,
        fallback: 'file-loader',
        name: 'fonts/[name].[hash:4].[ext]'
      }
    }
  ]
},
複製代碼

以上咱們就配置好了媒體文件相關的處理。

3.五、讓webpack識別vue文件

安裝依賴:

npm install vue-loader vue-template-compiler -D
複製代碼
  • vue-loader必須結合vue-template-compiler來使用,不然是不能完成轉換的。

首先配置module裏面的內容:

{
  test: /\.vue$/,
  use: [
    {
      loader: 'vue-loader',
      options: {
        compilerOptions: {
          preserveWhitespace: false
        }
      }
    }
  ]
}
複製代碼

配置裏面有個compilerOptions的參數preserveWhitespace爲false,這個意思是當它的值爲true時意味着編譯好的渲染函數會保留全部 HTML 標籤之間的空格。若是設置爲 false,則標籤之間的空格會被忽略。這可以略微提高一點性能可是可能會影響到內聯元素的佈局。具體參考此處:連接

配置好module後咱們還要引入插件,這個是必須的

// 引入vue-loader插件
const VueLoaderPlugin = require('vue-loader/lib/plugin');

// 添加到plugins中
new VueLoaderPlugin()
複製代碼

具體的你們能夠參考此處:連接

而後咱們還須要配置alias,這樣能夠減小路徑過長引用的麻煩:

resolve: {
  alias: {
    // 寫了這句,咱們能夠這樣寫代碼 import Vue from 'vue', 而且引入的是vue/dist/vue.runtime.esm.js這個版本,否則默認引入的是vue.js。這個在github的vue官方倉庫dist目錄下有解釋。
    'vue$': 'vue/dist/vue.runtime.esm.js',
    // 寫了這句,咱們能夠這樣寫代碼 import api from '@/api/api.js',省去處處找路徑定位到src的麻煩
    '@': path.resolve(__dirname, '../src')
  },
  // 添加一個 resolve.extensions 屬性,方便咱們引入依賴或者文件的時候能夠省略後綴
  // 咱們在引入文件時能夠這樣寫 import api from '@/api/api'。
  extensions: ['*', '.js', '.vue']
},
複製代碼

3.六、配置postcss

這個地方我配置了三個插件,autoprefixer、postcss-pxtorem、postcss-px-to-viewport,後兩個你只須要配置其中一個便可,主要看你開發使用的rem仍是vw,自行選擇便可。

npm install postcss-loader autoprefixer postcss-pxtorem postcss-px-to-viewport -D
複製代碼
  • postcss-loader 負責postcss相關的操做。
  • autoprefixer 爲瀏覽器添加不一樣的css3前綴。
  • postcss-pxtorem px自動轉換爲rem。
  • postcss-px-to-viewport px自動轉換爲vw|vh。

安裝好依賴事後,在項目的根目錄創建文件 postcss.config.js,而後在文件中輸入如下內容:

module.exports = {
    plugins: {
        // 這個工具能夠實現自動添加CSS3前綴
        "autoprefixer": {},
        // 若是你使用rem來實現移動端多設備適配,這個工具能夠把px轉換爲rem
        /* "postcss-pxtorem": {
        	rootValue: 37.5, // 指定轉換倍率,我如今設置這個表示1rem=37.5px;
        	propList: ['*'], // 屬性列表,表示你要把哪些css屬性的px轉換成rem,這個*表示全部
        	minPixelValue: 1, // 須要轉換的最小值,通常1px像素不轉換,以上才轉換
        	unitPrecision: 6, // 轉換成rem單位的小數點後的保留位數
        	selectorBalckList: ['van'], // 匹配不被轉換爲rem的選擇器
        	replace: true, // 替換包含rem的規則,而不是添加回退
        	mediaQuery: false // 容許在媒體查詢中轉換px
        }, */
        // 若是你使用vw來實現移動端多設備適配,這個工具能夠把px轉換爲vw
        "postcss-px-to-viewport": {
        	unitToConvert: 'px', // 把什麼單位轉換成vw
        	viewportWidth: 750, // 這個能夠按照你的設計稿來設置,是750就設置750,375就設置成375
        	unitPrecision: 6, // 轉換成vw單位的小數點後的保留位數
        	propList: ['*'], // 屬性列表,表示你要把哪些css屬性的px轉換成vw,這個*表示全部
        	viewportUnit: 'vw', // 使用的單位,目前可選單位有vw,vh。通常咱們都有vw
        	fontViewportUnit: 'vw', // 字體使用的單位
        	selectorBlackList: [], // 匹配不被轉換爲vw的選擇器
        	minPixelValue: 1, // 須要轉換的最小值,通常1px像素不轉換,以上才轉換
        	mediaQuery: false, // 容許在媒體查詢中轉換px
        	replace: true, // 替換包含vw的規則,而不是添加回退
        	exclude: [], // 忽略一些文件,好比「node_modules」,能夠是正則表達式
        	landscape: false,  // ......
        	landscapeUnit: 'vw', // ......
        	landscapeWidth: 568 // ......
        }
    }
}
複製代碼

而後呢,webpack配置加上:

{
  test: /\.(scss|sass)$/,
  use: [
    {
      loader: 'style-loader',
    },
    {
      loader: 'css-loader',
    },
    {
      loader: 'sass-loader',
      options: {
        implementation: require('dart-sass')
      }
    },
    {
      loader: 'postcss-loader'
    }
  ]
}
複製代碼

3.七、配置熱更新功能

安裝依賴:

npm install webpack-dev-server -D
複製代碼

安裝完成後,進行以下的配置:

// 引入webpack
const webpack = require('webpack');

// 配置devServer
devServer: {
  // 默認狀況不設置這個只能經過localhost:9000來訪問,如今能夠經過本機局域網ip來訪問,
  // 好比192.168.12.21:9000,手機在這個局網內也能夠訪問
  host: '0.0.0.0',
  hot: true,
  port: 9200,
  contentBase: './dist'
}

// 配置plugins
new webpack.NamedModulesPlugin(), // 輔助HotModuleReplacementPlugin插件
new webpack.HotModuleReplacementPlugin(), // 啓用熱更新必須的
複製代碼

四、定義環境變量

這個主要是定義這個玩意兒 process.env.NODE_ENV ,定義好這個咱們通常能夠來判斷什麼樣的環境執行什麼樣的代碼,咱們知道webpack的打包環境和開發環境配置通常是不同的,這裏不展開,後面會講。好比咱們在入口main.js裏面這樣來寫代碼判斷:

if(process.env.NODE_ENV === 'development'){ 
  //開發環境 do something
}else if(process.env.NODE_ENV === 'production') {
  //生產環境 do something
}
複製代碼

那麼定義這個環境怎麼操做呢,第一種是藉助webpack的插件DefinePlugin,

  • 使用DefinePlugin 咱們在plugins裏面加入如下代碼:
new webpack.DefinePlugin({
  'process.env': {
    NODE_ENV: JSON.stringify('development')
  }
}),
複製代碼

那麼咱們最終打包事後訪問到的process.env.NODE_ENV的值就是development。

另外一種使用webpack4本身集成了的環境判斷,咱們只須要在配置文件裏面聲明mode便可,推薦使用這種

  • 使用webpack4的mode參數
module.exports = {
  // 有none production development三個參數可選,不設置mode的話默認的process.env.NODE_ENV值爲production
  mode: "development",
  entry: {}
  .....
}
複製代碼

有了上面的mode設置,咱們照樣能取到process.env.NODE_ENV的值。 關於process.env.NODE_ENV的知識點這裏有幾篇文章能夠參考:

連接-1 連接-2 連接-3

五、集成Vue全家桶

安裝依賴

npm install vue vuex vue-router -S
複製代碼

安裝完依賴事後,在src目錄下新建一個App.vue的文件。寫入如下代碼:

<template>
  <div id="app">
    <router-view />
  </div>
</template>

<script>
export default {
  
}
</script>

<style lang="scss">

</style>
複製代碼

在src下再新建router、store兩個目錄,再目錄下分別新建router.js和store.js。順便再把其餘文件夾也建好,如components、assets、views。如今個人目錄結構以下圖所示:

4.png

main.js裏面修改成以下代碼:

import Vue from "vue";
import App from "./App.vue";
import router from "./router.js";

new Vue({
  router,
  render: h => h(App)
}).$mount("#app");
複製代碼

建好這些文件事後其實後面的代碼書寫就跟官方腳手架搭建好的寫法同樣,這裏就不在演示其它文件的代碼怎麼書寫了,到時能夠參考個人源代碼。

這兒引入vue-router和vuex事後,根據官方文檔作好配置便可開始測試,我這個只測試了vue和vue-router的功能正常,vuex暫時只創建了文件,但未進行實際引入測試。後面我會把源代碼提交到github供你們參考

這個時候,咱們直接npm run dev的話會打包,因此咱們須要把package.json的scripts中的dev改爲以下的代碼:

"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "dev": "webpack-dev-server --config ./build/webpack.config.js"
},
複製代碼

走到這步,若是你作好了前面的工做,理論上這兒執行npm run dev後就能看到效果了,我這兒的效果如圖所示:

6.gif

六、區分開發環境和生產環境

作單頁面開發咱們都知道,開發環境和生產環境是不太同樣的,平時使用官方cli時開發命令用的npm run dev,而打包發佈時npm run build。這裏面的配置確定是存在區別的。

如今在build目錄下新建webpack.dev.js和webpack.prod.js兩個文件,用來區分開發環境和生產環境。同時把開發環境和生產環境通用的配置都寫在webpack.config.js裏面。

  • 開發環境

一、webpack的mode屬性值設置爲development,開啓這個不會壓縮代碼。
二、須要webpack-dev-server和熱更新。
三、css不用提取到單獨文件並壓縮(固然你也能夠提出來)
四、不須要構建前清除上一次構建內容
五、不須要打包分析

  • 生產環境

一、webpack的mode屬性值設置爲production,開啓這個會壓縮代碼。
二、不須要webpack-dev-server和熱更新。
三、css要提取到單獨文件並壓縮
四、須要構建前清除上一次構建內容
五、須要打包分析

好了,大概瞭解了區別後,咱們還須要單獨安裝其餘沒有的依賴,先來波安裝命令,一把梭:

npm i clean-webpack-plugin copy-webpack-plugin @intervolga/optimize-cssnano-plugin mini-css-extract-plugin webpack-merge webpack-bundle-analyzer -D
複製代碼
  • clean-webpack-plugin 這個插件主要是用來清除上一次打包的內容,由於每次打包文件後面會生成新的hash值,不及時清除dist目錄會累積不少文件,還容易形成沒必要要的麻煩。
  • copy-webpack-plugin 有時候咱們存在靜態資源,也就是不參與打包的文件,這時候咱們就須要這個插件來實現拷貝,保證資源可訪問。
  • @intervolga/optimize-cssnano-plugin 分離出來的css文件進行壓縮。
  • mini-css-extract-plugin 用於把css單獨分離出來。
  • webpack-merge 合併webpack配置的插件。
  • webpack-bundle-analyzer 打包事後能夠看到各個js文件所佔的大小以及在項目中的比例。

接下來修改相關的文件

6.一、webpack.config.js

注:這兒我把miniCssExtractPlugin放在通用配置文件裏面了,開發和生產都使用,這裏格式有點亂了-_-!

// build/webpack.config.js
// node.js裏面自帶的操做路徑的模塊
const path = require("path");
// 引入htmlWebpackPlugin自動導入js文件
const htmlWebpackPlugin = require('html-webpack-plugin');
// 引入vue-loader插件
const VueLoaderPlugin = require('vue-loader/lib/plugin');
// 用於提取css到文件中
const miniCssExtractPlugin = require('mini-css-extract-plugin');
// 用於壓縮css代碼
const optimizeCssnanoPlugin = require('@intervolga/optimize-cssnano-plugin');
// 拷貝靜態資源
const copyWebpackPlugin = require('copy-webpack-plugin');

module.exports = {
  // webpack打包的入口文件
  entry: {
    main: path.resolve(__dirname, "../src/main.js")
  },
  // webpack打包的輸出相關的額配置
  output: {
    // 打包事後的文件的輸出的路徑
    path: path.resolve(__dirname, "../dist"),
    // 打包後生成的js文件,帶hash值來保證文件的惟一性
    filename: "js/[name].[hash:4].js",
    // 生成的chunk文件名
    chunkFilename: "js/[name].[hash:4].js",
    // 資源的引用路徑(這個跟你打包上線的配置有關係)
    publicPath: "/"
  },
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'babel-loader'
          }	
        ]
      },
      {
        test: /\.(scss|sass)$/,
        use: [
          {
            loader: miniCssExtractPlugin.loader, // 使用miniCssExtractPlugin.loader代替style-loader
          },
          {
            loader: 'css-loader',
          },
          {
            loader: 'sass-loader',
            options: {
              implementation: require('dart-sass')
            }
          },
          {
            loader: 'postcss-loader'
          }
        ]
      },
      {
				test: /\.(jpe?g|png|gif)$/i,
				use: [
					{
						loader: 'url-loader',
						options: {              
              limit: 5120, // 當文件大於5kb時走file-loader相關的配置             
              esModule: false, // 這個參數要設置成false,否則生成圖片的路徑時[object Module]              
              fallback: 'file-loader', // 當文件大於5kb時走file-loader相關的配置
              name: 'images/[name].[hash:4].[ext]' // 生成的路徑和文件名
						}
					}
				]
			},
      {
				test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
				use: [
					{
						loader: 'url-loader',
						options: {
              limit: 5120,
              esModule: false,
              fallback: 'file-loader',
              name: 'media/[name].[hash:4].[ext]'
						}
					}
				]
			},
			{
				test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/i,
				use: [
					{
						loader: 'url-loader',
						options: {
              limit: 5120,
              esModule: false,
              fallback: 'file-loader',
              name: 'fonts/[name].[hash:4].[ext]'
						}
					}
				]
      },
      {
        test: /\.vue$/,
        use: [
          {
            loader: 'vue-loader',
            options: {
              compilerOptions: {
                preserveWhitespace: false
              }
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new htmlWebpackPlugin({
      // 指定模板
      template: path.resolve(__dirname, '../public/index.html'),
      // 輸出的文件
      filename: path.resolve(__dirname, '../dist/index.html')
    }),
    new VueLoaderPlugin(),
    // 新建miniCssExtractPlugin實例並配置
    new miniCssExtractPlugin({
      filename: 'css/[name].[hash:4].css',
      chunkFilename: 'css/[name].[hash:4].css'
    }),
    // 壓縮css
    new optimizeCssnanoPlugin({
      sourceMap: true,
      cssnanoOptions: {
        preset: ['default', {
          discardComments: {
            removeAll: true,
          },
        }],
      },
    }),
    // 拷貝靜態資源
    new copyWebpackPlugin([{
      from: path.resolve(__dirname, '../public'),
      to: path.resolve(__dirname, '../dist')
    }])
  ],
  resolve: {
		alias: {
      // 寫了這句,咱們能夠這樣寫代碼 import Vue from 'vue'
      'vue$': 'vue/dist/vue.runtime.esm.js',
      // 寫了這句,咱們能夠這樣寫代碼 import api from '@/api/api.js',省去處處找路徑定位到src的麻煩
      '@': path.resolve(__dirname, '../src')
    },
    // 添加一個 resolve.extensions 屬性,方便咱們引入依賴或者文件的時候能夠省略後綴
    // 咱們在引入文件時能夠這樣寫 import api from '@/api/api'。
    extensions: ['*', '.js', '.vue']
	}
};
複製代碼

6.二、webpack.dev.js

// build/webpack.dev.js
// 引入webpack
const webpack = require('webpack');
// 引入webpack通用配置
const webpackCommonConfig = require('./webpack.config.js');
// 引入配置合併插件
const merge = require('webpack-merge');

module.exports = merge(webpackCommonConfig, {
  // 指定模式,這兒有none production development三個參數可選
  // 具體做用請查閱官方文檔
  mode: "development",
  plugins: [
    // 輔助HotModuleReplacementPlugin插件
    new webpack.NamedModulesPlugin(),
    // 啓用熱更新必須的
    new webpack.HotModuleReplacementPlugin(),
  ],
  devServer: {
    // 默認狀況不設置這個只能經過localhost:9000來訪問,如今能夠經過本機局域網ip來訪問,
    // 好比192.168.12.21:9000,手機在這個局網內也能夠訪問
    host: '0.0.0.0',
    hot: true,
    port: 9200,
    contentBase: './dist'
  }
});
複製代碼

6.三、webapck.prod.js

// build/webpack.prod.js
// 引入清除打包後文件的插件(最新版的須要解構,否則會報不是構造函數的錯,並且名字必須寫CleanWebpackPlugin)
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
// 引入配置合併插件
const merge = require('webpack-merge');
// 引入通用配置
const webpackCommonConfig = require('./webpack.config.js');
// 分析打包後模塊分析插件
const webpackBundleAnalyzer = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

module.exports = merge(webpackCommonConfig, {
  // 指定模式,這兒有none production development三個參數可選
  // 具體做用請查閱官方文檔
  mode: "production",
  plugins: [
    new CleanWebpackPlugin(),
    new webpackBundleAnalyzer({
      analyzerMode: 'static'
    }),
  ]
});
複製代碼

配置好相關文件後咱們再修改下package.json中的scripts:

"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "dev": "webpack-dev-server --config ./build/webpack.dev.js",
  "build": "webpack --config ./build/webpack.prod.js"
},
複製代碼

最後

相關配置到這兒就結束了,後期會繼續更新優化方面的內容,如代碼拆分這些,本篇只是如何來搭建一個環境並跑起來,並無優化相關的內容。若有錯誤還請你們交流指出,以爲不錯的話點個贊再走吧!

相關代碼我已經提交到倉庫了,連接地址

相關文章
相關標籤/搜索