webpack 配置詳解

最近在學習webpack,邊學邊練習,下面是對一些應用到的屬性、插件記錄分享出來,也方便之後查找與複習,過程當中碰到了一些坑,在註釋中有說明:css

const path = require('path')
const webpack = require("webpack")

const ExtractTextPlugin = require("extract-text-webpack-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');

function parseUrl(dir) {
    let mark = '\\'.indexOf(dir) !== -1 ? '\\' : '\/';
    return dir.split(mark).slice(0, -1).join(mark);
}
/**
 * 說明
 * 
 * 一、能夠經過import(\/* webpackChunkName: "lodash_file" *\/ 'lodash').then()這種方式動態添加Chunk,
 *      打包之後會獨立成一個文件,註釋部分結合output- chunkFilename 命名打包後的文件名
 * 二、chunk名稱,能夠經過entry進行定義,也有一些默認的chunk包
 */
module.exports = {
    entry: {  // 命名chunk,後面能夠經過屬性名調用到
        app: './app/index.js',
        check: './src/check.js',
        repeat: './src/repeat.js',
        vender: [
            'colors',
            'lodash'
        ]
    },
    
};

output

output: {
    // 文件用hash打包的時候([name].[chunkhash].js),須要關閉熱替換,生產環境是不須要熱替換的
    // filename: '[name].bundle.js',
    filename: '[name].[chunkhash].js',
    path: path.resolve(parseUrl(__dirname), 'dist'),
    publicPath: '/',  // webpack-dev-middleware插件用到的公共路徑,在server.js文件中會用到
    chunkFilename: '[name].bundle.js',  // 能夠控制動態加載文件名稱
},

devtool

/**
 * devtool 
 * 
 * 追蹤錯誤和警告,打包之後,使用打包文件也能夠追蹤到哪一個文件出錯,能夠有多個選項,
 * 參見:https://segmentfault.com/a/1190000004280859 或 https://doc.webpack-china.org/configuration/devtool (官網)
 * 
 * 開發環境推薦使用 cheap-module-eval-source-map
 * 理由:
 * 一、不生成列信息,能夠大幅提升 souremap 生成的效率,若是須要列信息,有些瀏覽器也能夠自動生成列信息
 * 二、使用 eval 方式可大幅提升持續構建效率,參見 https://doc.webpack-china.org/configuration/devtool 效率對照表
 * 
 * 生產環境使用 source-map
 */
devtool: 'cheap-module-eval-source-map',

watch

// 監聽項目是否有改動,若是有改動直接影響修改
watch: true,
watchOptions: {
    // 從新構建一次的延遲時間,在這段時間內有其餘變更,會收集起來一塊兒構建
    aggregateTimeout: 300,
    poll: 1000,  // 每秒檢查一次變更
    ignored: /node_modules/  // 忽略node_modules文件夾中的文件變更,提高性能
},

devserver

//  構建一個web服務器
devServer: {
    contentBase: '../dist',  // 指定服務響應目錄
    hot: true,  // 啓用熱替換模塊 須要在入口文件中進行配置監聽,詳細參考文檔https://doc.webpack-china.org/guides/hot-module-replacement/
},

module

module: {
    // 解析文件時匹配相對應的loader
    rules: [
        {
            test: /\.css$/,
            use: ["style-loader", "css-loader"],
            use: ExtractTextPlugin.extract({  // 樣式獨立打包
                use: 'css-loader'
            })
        },
        {
            test: /\.(png|svg|jpg|gif)$/,
            use: [
                'file-loader'
            ]
        }
    ]
},

plugins

plugins: [
    // 分離css依賴,生成獨立樣式包,放入參數文件中(沒有會自動生成)
    new ExtractTextPlugin('styles.css'),

    // 生成html模板,調用了webpack生成的全部包
    new HtmlWebpackPlugin({
        title: 'Output Management',
        filename: 'index.html',
        // chunksSortMode: 'none',  // 模塊排列順序
        // chunks: ['app'],  // 渲染模板,輸入入口定義的模板名稱
        excludeChunks: ['check'], // 排除的渲染模板,以輸入入口定義的模板名稱爲準
        template: 'index.html'  // 模板路徑,在現有模板的基礎上將打包生成的chucks添加上去
    }),

    // 先清除文件夾後生成,避免沒必要要的文件存在,根目錄下的不能清除
    new CleanWebpackPlugin(['../dist']),

    // prints more readable module names in the browser console on HMR updates
    new webpack.NamedModulesPlugin(),

    /**
     * 熱替換
     * 
     * 須要在devServer屬性配置 hot:true 而且建立組件 啓動熱替換
     * 經過 module.hot 屬性,用來接收監聽接口 放到入口文件中
     * 使用熱替換能夠實現局部刷新,節省開發時間
     * 若是沒有引入熱替換,修改後就會所有刷新,影響響應速度
     * HMR 修改樣式表時,須要在hot下引入接口,
     * 注意:使用熱替換監聽樣式修改時,不能啓動樣式表獨立打包模式,若是啓動瀏覽器就不能響應到樣式的修改
     * API連接:https://doc.webpack-china.org/api/hot-module-replacement
     */
    new webpack.HotModuleReplacementPlugin(),

    // 代碼壓縮,能夠配置source map模式
    // new UglifyJSPlugin({
    //     // 使用source map模式(devtool屬性必須設置爲devtool: 'source-map')
    //     // 做用:在生產環境中也能夠很方便的調試代碼,相似於devtool: 'inline-source-map'模式
    //     sourceMap: true
    // }),

    new webpack.DefinePlugin({
        // 定義環境變量,能夠在打包入口文件中獲取到,相應環境變量
        'process.env': {
            'NODE_ENV': JSON.stringify('production')
        }
    }),

    // 將公共的依賴模塊提取到已有的入口 chunk 中 
    // 能夠建立多個
    // 能夠提取自帶 chunk 獨立打包,好比:boilerplate 、 manifest ....
    new webpack.optimize.CommonsChunkPlugin({
        name: 'common', // chunk 的名稱
        filename: 'common_file.js',  // 輸出 chunk 文件名

        /**
         * 公共 chunk 以前所須要包含的最少數量的 chunks(也就是有幾個chunk依賴)
         * 
         * 一、可選擇 number|Infinity(立刻生成 公共chunk,但裏面沒有模塊)|function(module, count) -> boolean,
         * 二、能夠調用函數 返回true的文件打包成獨立文件,false 不會獨立成包
         * 
         * @param module 模塊信息
         * @param count 調用數量
         */
        minChunks: function (module, count) {
            // 禁止打包樣式相關文件(有組件針對樣式文件打包)
            if (module.resource && (/^.*\.(css|scss)$/).test(module.resource)) {
                return false;
            }
            // node_modules文件夾中的文件獨立打包
            return module.context && module.context.indexOf("node_modules") !== -1;
        }
    }),

    // 能夠根據 entry 或name名稱進行分離打包,
    // 若是和 chunk = 'common' 共用,會報錯
    new webpack.optimize.CommonsChunkPlugin({
        name: "vender",
        minChunks: Infinity
    }),

    // 避免hash發生變化
    // new webpack.HashedModuleIdsPlugin(),
]

若是有什麼不對的地方,歡迎指正。html

相關文章
相關標籤/搜索