Webpack 實戰入門系列(三):生產配置、樣式文件分離及輸出清理

本文由公衆號 字節逆旅 的主筆 慢一拍 寫做而成,慢一拍 已認證成爲圖雀社區專欄做者,後續將爲你們帶來一系列 Webpack 的文章,敬請期待✌️。歡迎加入圖雀社區,一塊兒創做精彩的免費技術實戰教程,加速技術的傳播!css

若是您以爲咱們寫得還不錯,記得 點贊 + 關注 + 評論 三連,鼓勵咱們寫出更好的教程💪 今天帶來webpack入門之三,這多是入門系列最後一篇了,後面會進入進階系列。之因此說是入門最後一篇,是由於我以爲不少項目只須要有這個入門級別就能夠很好的實現升級維護了。html

如今vue、react很流行,新項目基本用這些新框架,組件化開發確實是趨勢,可是他們再怎麼發展也離不開構建工具,頂多在webpack等工具上進行再封裝。如今vuecli3出來後,我感受學習成本反而變高了,直觀感受就是文檔不清爽,知識零碎。其實回到本源,vuecli3就是基於webpack來的,並且webpack自己很是好學,能夠由淺到深,逐步深刻。你能夠不用學vue、react,只要你會html+css+js就能夠用上這個打包工具。不少人不懂webpack是由於一開始就沒接觸過,而後最早接觸的反而是vue或者react框架,結果組件api已經學暈了,忽然據說這個實際上是webpack的東西,一下就更懵了,因此在不懂原理的狀況下,別人的包裝讓你更加的迷茫。有些人只想會用就行,有些人是有點搞不懂的就想搞明白。那若是你是個前端,想搞清楚本質本源的東西,真的建議你學下webpack。就從這篇入門開始吧,一小時入門webpack前端

本文是基於前面兩篇文章來的,每一篇都不長,照着敲代碼會很容易上手。vue

生產配置

前面第一篇提到過webpack.config.js文件中的mode這個配置參數用來指定當前的運行環境的,這個配置是webpack4提出來的,它有三個值:"production" | "development" | "none",production就是生產環境,即最終部署環境;development是開發環境;none即不指定環境因素,默認是production。開發和生產環境仍是有很大區別的,按官網說法,在開發環境中,咱們須要具備強大的、具備實時從新加載或熱模塊替換能力的 source map 和本地服務。而在生產環境中,咱們的目標則轉向於關注更小的輸出文件,更輕量的 source map,以及更優化的資源,以改善加載時間。這裏提到的souce map,意思就是資源地圖,後面進階部分會講到,你能夠上官網查下。node

剛剛講了兩種環境的區別,主要是爲了強調把兩種環境的配置分開管理的重要性。那問題來了,用兩個配置,那把webpack.config.js拷貝一份,將mode分別設置爲兩個環境不就能夠了?這沒問題,可是也能夠將公用部分抽出來,在各個環境中引用公用部分,這樣管理起來更方便。react

這裏就要提到一個工具:webpack-merge,能夠專門用來合併webpack配置,能夠經過npm安裝;webpack

安裝

npm install --save-dev webpack-merge
複製代碼

抽離公用配置

在根目錄新建一個webpack.common.js文件,把webpack.config.js文件內容拷貝一份進去,刪掉devServer、watch部分,只留下公用部分。git

生產及開發環境配置

而後將webpack.config.js重命名爲webpack.dev.js,再將內容修改成如下內容:es6

'use strict'
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
    devtool: 'inline-source-map',
    watch: true,
    devServer: {
     contentBase: './dist',
     hot: true
   }
 });
複製代碼

再新建一個webpack.prod.js文件,即生產環境配置,輸入如下內容:github

'use strict'
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {});
複製代碼

npm scripts

修改npm scripts,將原來的啓動配置修改下,將dev配置修改成

"dev""webpack-dev-server --config webpack.dev.js --open"
複製代碼

由於以前都是默認從webpack.config.js中啓動不用寫文件名,如今開發和生產環境分開,就要將啓動指向文件標名。dev表明開發環境,咱們開發時就運行 npm run dev看瀏覽器運行效果。那麼構建的時候,就要調用生產環境的配置了,在原來的構建節點build後面加上啓動文件就行。

"build""webpack --config webpack.prod.js"
複製代碼

而後能夠運行下npm run dev看下效果,沒問題

再運行下npm run build打包,也是沒問題的。

總結下,就是將公用部分抽出來獨立,像loader及插件這種常常會添加修改的就單獨放,後期只修改common.js,應用到開發、生產環境,就在對應的配置文件中merge這個工具合併就是一個完整配置了。這樣即進行了環境區分,並且公共配置被抽離,實現了互不干擾也不會增長工做量。

css文件分離構建

目前咱們打包後,js代碼還有樣式全輸出到index.js文件中,前面咱們在講到圖片構建時,將圖片放在樣式中,而後經過url-loader打包成base64數據,因此整個的輸出文件中就看起來一堆的東西,分不清你我,很混亂。這裏就講到一個插件ExtractTextWebpackPlugin,能夠將樣式與js分離。

安裝ExtractTextWebpackPlugin

npm install --save-dev extract-text-webpack-plugin
複製代碼

接下來要注意了,由於咱們已經將生產和開發環境的配置進行了分離,並且這個插件是要在生產環境,也就是構建的時候發揮做用,因此先將以前在公用配置文件webpack.common.js中的樣式相關loader刪掉並移植到webpack.dev.js文件中,最後在webpack.prod.js文件中應用此插件。直接上代碼,三個配置文件具體代碼以下:

webpack.common.js

'use strict'
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    entry: {
        index: './src/index.js',
    },
    output: {
        path: path.join(__dirname,'dist'),
        filename: 'index.js'
    },
    plugins: [
        new HtmlWebpackPlugin({
           title: 'leaningwebpack',
           filename: 'webpack-index.html',
           favicon: 'webpack.ico'
        }),
        new webpack.HotModuleReplacementPlugin()
    ],
    module: {
        rules: [
            {
                test: /.js$/,
                use: 'babel-loader',
                exclude: /node_modules/
            },
            {
                test: /.(jpg|png|gif|jpeg)$/,
                use: [{
                    loader:'url-loader',
                    options: {
                        limit:160000,
                        name: 'imgs/[name].[hash].[ext]'
                    }
                }]
            }
         ]
      }
}
複製代碼

webpack.dev.js

'use strict'
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
    devtool: 'inline-source-map',
    watch: true,
    devServer: {
     contentBase: './dist',
     hot: true
   },
   module: {
       rules: [
        {
            test: /.css$/,
            use: [
                'style-loader',
                'css-loader'
            ]
        },
        {
            test: /.less$/,
            use: [
                'style-loader',
                'css-loader',
                'less-loader'
            ]
        },
       ]
   }
 });
複製代碼

webpack.prod.js

'use strict'
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = merge(common, {
    plugins: [
        new ExtractTextPlugin({filename: "style.css"})],
    module: {rules: [
        {
            test: /.less$/,
            use: ExtractTextPlugin.extract({
                fallback: 'style-loader',
                use: ['css-loader', 'less-loader']
              })
        }]
    }
 });

複製代碼

而後運行npm run build,就會看到在dist目錄下生成了樣式文件:style.css,這個文件在html文件中被引用了。咱們運行npm run dev時,它會走開發環境的配置,仍然能夠正常解析樣式文件。

清理輸出文件

接下來說最後webpack入門的最後一個知識點:清理輸出文件。咱們能夠看到在dist文件夾裏,有一些歷史文件index.html,這是我在webpack.common.js文件裏修改了東西,輸出文件變了,可是以前的文件仍然會存在,這樣日積月累就會有不少垃圾。這個比較簡單,安裝一個插件,引用一下就好了,記住,這個也是生產環境中配置。

安裝clean-webpack-plugin

npm install clean-webpack-plugin --save-dev
複製代碼

插件配置

const CleanWebpackPlugin = require('clean-webpack-plugin');

 plugins: [
        new CleanWebpackPlugin(),
        new ExtractTextPlugin({filename: "style.css"})],
複製代碼

代碼我就不寫完整了,應該能明白怎麼回事了吧。而後運行npm run build,看下效果。

結果報錯了:CleanWebpackPlugin is not a constructor。

在網上找了下,插件引用須要這麼寫:

const {CleanWebpackPlugin} = require('clean-webpack-plugin');
複製代碼

{CleanWebpackPlugin}這是es6的新語法,將變量直接寫入大括號就是一個對象了。爲何要這麼寫呢?能夠看看這個插件的源碼,在依賴包裏找到這個文件

exports.CleanWebpackPlugin = void 0;
class CleanWebpackPlugin = { ... }
exports.CleanWebpackPlugin = CleanWebpackPlugin;
複製代碼

也就是說,這個插件導出的是一個變量exports.CleanWebpackPlugin,可是咱們須要的是一個類CleanWebpackPlugin ,因此加上括號就能夠了,我我的以爲這是插件的一個bug。

修改好後,再運行npm run build就能夠看到效果了,dist目錄下以前的文件刪除了,生成了新文件。

好了,入門系列今天收官了,但願你能有收穫。歡迎關注,後面會有高階用法介紹。封城期間我開始真正打理公衆號,原創確實不易,若是以爲對你有用,就點個在看吧!

代碼地址:github.com/bridgeToVil…

若是本文對你有幫助就點個在看吧,歡迎轉發哦!

想要學習更多精彩的實戰技術教程?來圖雀社區逛逛吧。

若是您以爲咱們寫得還不錯,但願您能給❤️這篇文章點贊❤️哦

相關文章
相關標籤/搜索