webpack4.0+vue+es6配置

super_YUE發表於2019-02-22

用webpack4.0做更多事情

上一篇webpack入門文章中,我們學會了怎麼使用webpack搭建一個前端工程,瞭解了webpack的一些核心概念。但是webpack的功力遠不止如此,在本文中,我們將學習如何使用webpack來做更多的事情,如何進行環境分離,如何配置es6,再配置vue,使用vue來進行開發。

這篇文章是入門文章的延續,不太瞭解webpack的同學可以先從入門文章看起,循序漸進。

開發與生產環境的分離

在實際開發中,會有許多環境,有 開發環境,生產環境,測試環境,預發環境....(因公司而異)。最常見的兩種是開發環境和生產環境。在不同的環境會有很多不同的配置。所以我們需要把不同環境的配置檔案從webpack.config.js檔案中分離出來。

首先進行目錄的改造。首先安裝依賴,用於融合配置檔案。

npm install -D webpack-merge
複製程式碼
webpack-demo
|- config
    |- webpack.base.js
    |- webpack.dev.js
    |- webpack.pro.js
|- package.json
|- src
    |- 略
複製程式碼

webpack.base.js

const path = require("path");
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: {
        index: path.resolve(__dirname,'./src/index.js'),
    },
    output: {
        filename: '[name].[hash].js',
        path: path.resolve(__dirname,'../dist'),
    },
    module: {
        rules:[
            {
                test: /\.css$/,
                use: [
                    "style-loader",
                    "css-loader"
                ]
            },{
                test: /\.(png|svg|jpg|gif)$/,
                use:{
                    loader:'url-loader',
                    options: {
                        limit: 8192,
                        name: 'images/[name].[ext]?[hash]'
                    }
                }
            }
        ]
    },
    plugins:[
        new HtmlWebpackPlugin({
            title:'WebpackTest'
        })
    ]
}
複製程式碼

output檔名修改: 我們需要對output的filename選項進行修改。在使用者訪問網頁之後,會載入dist包中的bundle.js,並且進行快取。在我們進行版本更新以後,如果載入檔名還是bundle.js的話。瀏覽器不會拉去新的bundle.js資源,會直接使用瀏覽器快取的資源。所以我們需要將每次打包後的資源名都命名不同。[name].[hash].js會根據檔案內容給每個檔名加上唯一的雜湊,這樣就不會出現重名檔案了。

開發環境(dev)

webpack.dev.js

const merge = require("webpack-merge");
const base = require("./webpack.base");
const webpack = require("webpack");

module.exports = merge(base ,{
    mode: 'development',
    devtool: 'source-map',
    devServer:{
        compress: true, //啟用壓縮
        port: 1207,     //埠
        open: false,    //自動開啟瀏覽器
        hot: true
    },
    plugins:[
        new webpack.HotModuleReplacementPlugin()
    ]
})
複製程式碼

首先介紹一下開發環境下我們需要進行配置的幾點

  • source-map:source-map在開發中的用處很大,在瀏覽器允許的程式碼是經過編譯以後的程式碼,在出現一些錯誤的時候,如果不使用source-map的時候,錯誤無法定位到原始碼中。使用了source-map以後,可以直接定位到錯誤出現的行。配置source-map只需要將devtool屬性配置為source-map就可以。
  • devserver配置:devserver屬性可以對開發環境選項進行一些配置,比如:自動開啟瀏覽器,服務埠號,熱更替,是否壓縮等。
  • 模組熱更替(HotModuleReplacementPlugin): 模組熱更替允許在更新各種模組的時候,無需完全重新整理頁面,這個功能在開發環境中非常實用。最簡單的應用場景,你在寫一些樣式的時候,需要自己配置一些資料上去,這時候你需要調整字型大小。使用了模組熱更替之後會頁面不用重新整理就可以看到效果,省去了重新配置資料。在開啟熱更替時,還需要對模組熱更替外掛進行配置,否則會報錯。

生產環境(pro)

const merge = require('webpack-merge');
const base = require("./webpack.base.js");
const CleanWebpackPlugin = require('clean-webpack-plugin');
const path = require("path");

module.exports = merge(base ,{
    mode: 'production',
    plugins: [
        new CleanWebpackPlugin(['dist'],{
            root: path.resolve(__dirname,'../'),
        })
    ],
})
複製程式碼
  • clean-webpack-plugin:用於刪除檔案,在每次打包時,dist資料夾都會出現新的檔案,如果不進行刪除處理的話,會一直累加到dist資料夾裡面。所以這裡使用clean-webpack-plugin外掛,每次打包的時候都會先刪除之前的dist檔案。

模式(mode)

在入門篇中,我們每次編譯後都會出現he 'mode' option has not been set的警告。這是webpack4新增的mode屬性,有兩種mode,development和production.

  • development模式:
    • process.env.NODE_ENV的值設為 development,過去需要通過webpack.DefinePlugin進行配置。
    • 提供註釋、開發階段的詳細錯誤日誌和提示。
  • production模式:
    • process.env.NODE_ENV的值設為 production,過去需要通過webpack.DefinePlugin進行配置。
    • 開啟所有的優化程式碼,壓縮外掛UglifyJsPlugin,過去需要自行配置。
    • 去掉一些只在開發中執行的程式碼。

process.env.NODE_ENV值用於再開發中進行環境判斷。

package.json

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

再對npm script進行修改,指定對應配置檔案。

es6配置

下面我們進行es6的配置,由於es6未被所有瀏覽器全面支援,所有我們在使用的時候還想需要將其轉換為es5.主要用到的工具是babel,先進行babel依賴的安裝。

npm i -D @babel/core @babel/plugin-transform-runtime @babel/preset-env babel-loader
複製程式碼

webpack.base.js

...略
module:{
    rulse:[
        ...略
        {
            test: /\.js$/,
            loader: 'babel-loader',
            exclude: /node_modules/,
        }
    ]
}
複製程式碼

配置loader,這裡的exclde選項用於忽略一些檔案(敲黑板),減少webpack的處理量。/node_modules/都是已經轉好的檔案。

新增.babelrc檔案

webpack-demo
|- config
    |- 略
|- package.json
|- src
    |- 略
|- .babelrc
複製程式碼
{
    "presets": ["@babel/preset-env"], 
    "plugins": ["@babel/plugin-transform-runtime"] 
}
複製程式碼
  • presets(設定轉碼規則):過去需要進行規則集指定,現在使用@babel/preset-env搭配@babel/core解決
  • plugins(外掛):transform-runtime 外掛表示不管瀏覽器是否支援ES6,只要是ES6的語法,它都會進行轉碼成ES5

resolve

這些選項能設定模組如何被解析。在vue開發中通常使用的@/xxx/xxx就是將@符號配置為src目錄。這樣webpack就能快速的找到該路徑,這樣的配置不僅可以方便開發,而且可以優化構建時間,減輕webpack的工作量。另外還可以配置字尾名的自動補全。

resolve: {
    extensions: [ '.js', '.vue', '.scss', '.css'], //字尾名自動補全
    alias: {                                       //別名
        '@': path.resolve(__dirname, '../src'),
    }
},
複製程式碼

vue配置

最後我們進行vue的配置,先安裝依賴。

npm i -D vue vue-loader vue-style-loader vue-template-compiler
複製程式碼
  • vue-loader是vue的loader,vue檔案是一個SFC類檔案,vue-loader會將其解析成為三部分,template部分用於渲染檢視,js,style。
  • vue-style-loader用於處理vue-loader解析後的style.
  • vue-template-compiler用於處理解析解析後的template.

先進行目錄改造

webpack-demo
|- config
    |- 略
|- package.json
|- src
    |- components
        |- HelloWorld.vue
    |- views
        |- App.vue
    |- asset
        |- img.png
        |- style.css
    |- index.html
    |- index.js
|- .babelrc
|- package.json
複製程式碼

webpack.base.js

const path = require("path");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const ProgressBarPlugin = require('progress-bar-webpack-plugin');

module.exports = {
    ...略
    module:{
        rules:[
            {
                test: /\.css$/,
                use: [
                    "style-loader",
                    "vue-style-loader",
                    "css-loader"
                ]
            },{
                test: /\.(png|svg|jpg|gif)$/,
                use:'url-loader',
                
            },{
                test: /\.js$/,
                loader: 'babel-loader',
                exclude: /node_modules/,
            },{
                test:/\.vue$/,
                use: 'vue-loader'
            }
        ]
    },
    plugins:[
        new VueLoaderPlugin(),
        new HtmlWebpackPlugin({
            filename: './index.html',     //檔名
            template: './src/index.html', //模板檔案
        })    
    ]
}
複製程式碼

在這裡我們還需要安裝VueLoaderPlugin(),並且需要進行HtmlWebpackPlugin的重新配置,我們需要使用自己的template,因為必須建立一個div入口,將vue例項掛載在這上面。按原來方式使用該外掛的話,無法建立div入口。

index.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>webpackStudy</title>
</head>
<body>
    <div id="root"></div>
</body>
</html>
複製程式碼

index.js

import Vue from 'vue'
import App from './views/APP'
import '@/asset/style'

new Vue({
    el:'#root',
    render: h => h(App)
})
複製程式碼

HelloWorld.vue

<template>
    <div>
        <img src="../asset/img.png" alt="">
        <p>一起學習前端吧</p>
    </div>
</template>

<script>
export default {

}
</script>

<style scoped>
p{
    font-size: 50px;
}
</style>
複製程式碼

App.vue

<template>
  <div id="app">
    <hello-world></hello-world>
  </div>
</template>

<script>
import HelloWorld from '@/components/HelloWorld'

export default {
  name: "App",
  components: {
    HelloWorld
  }
};
</script>
複製程式碼
  • index.js依舊是我們的webpack入口檔案,我們將css檔案和APP.vue入口檔案引入,進行vue例項化,掛載在root節點上(index.html檔案的root節點)。
  • 然後就可以開始元件開發啦。

小工具

當我們的元件躲起來了以後,webpack 打包非常耗時,我們來安裝一個ProgressBarPlugin來檢視打包進度。

npm i -D progress-bar-webpack-plugin
複製程式碼
plugins:[
    new ProgressBarPlugin()//打包進度條
]
複製程式碼

github

原始碼在我的github倉庫step2分支,希望能夠幫助到大家。

END

webpack這個技能棧將會是前端工程師必備的,對於小白來說,剛開始可能會不太好理解,其實不用把他看到太難,就是檔案從哪來到哪裡去的一個打包工具而已,我們所做的只是把他的各個模組的從哪來到哪去的問題配好,將每一部分都弄懂。接下來需要做的就是在此基礎上進行開發了。