webpack使用配置優化

使用vue+webpack模塊化開發也有一段時間了,這過程當中遇到過不少的問題。在驚奇於webpack的模塊化打包同時,也列舉幾個常常遇到的問題,以及相應的解決辦法;css

基本配置:html

var path = require('path');
var webpack = require('webpack');
var del = require('del'); // 刪除文件和目錄
var ExtractTextPlugin = require('extract-text-webpack-plugin'); // 提取樣式
var commonPlugin = new webpack.optimize.CommonsChunkPlugin('common'); // 抽離打包

module.exports = {
    entry: { // 指令文件入口,能夠爲多個入口,打包成多個文件
        main: './src/main.js',
        vendors: ['lodash','vue','element-ui'] // 須要抽離打包的第三方類庫
    },
    output: {
        path: path.resolve(__dirname, './dist'),
        publicPath: '/dist/',
        filename: '[name].js',
        chunkFilename: '[name].[hash].js'
    },
    module: { // 配置loader和規則,loader加載和打包很耗費時間
        rules: [{
            test: /\.vue$/,
            loader: 'vue-loader'
        }, {
            test: /\.(css|scss|sass)$/,
            use: ExtractTextPlugin.extract({ // 將內嵌在頁面裏的CSS樣式提取出來
                fallback: 'style-loader',
                use: [{
                    loader: 'css-loader'
                }, {
                    loader: 'sass-loader'
                }]
            })
        }, {
            test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
            loader: "file-loader?limit=10000&mimetype=application/font-woff&name=fonts/[name].[ext]"
        }, {
            test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
            loader: "file-loader?name=fonts/[name].[ext]"
        }, {
            test: /\.js$/,
            loader: 'babel-loader',
            exclude: /node_modules/
        }, {
            test: /\.(png|jpg|gif|svg)$/,
            loader: 'file-loader',
            options: {
                name: './image/[name].[ext]?[hash]'
            }
        }]
    },
    resolve: {
        alias: { // 配置模塊別名
            'vue$': 'vue/dist/vue.esm.js',
            'views': 'src/views',
            'components': path.resolve(__dirname, 'src/components')
        }
    },
    devServer: {
        historyApiFallback: true,
        noInfo: true
    },
    performance: {
        hints: false
    },
    devtool: '#eval-source-map',
    plugins: [
        new ExtractTextPlugin('[name].css'), // 抽離CSS代碼到樣式文件
        new webpack.optimize.CommonsChunkPlugin({ // entry.vendors列出的第三方類庫都會被打包成一個單獨的vendors.js文件
            name: 'vendors'
        }),
        commonPlugin // 打包成common.js文件,包含webpack引導和最新build的hash值
    ]
}

if (process.env.NODE_ENV === 'production') {
    del('./dist'); // 從新build前先清空dist目錄
    module.exports.devtool = '#source-map'
    // http://vue-loader.vuejs.org/en/workflow/production.html
    module.exports.plugins = (module.exports.plugins || []).concat([
        new webpack.DefinePlugin({
            'process.env': {
                NODE_ENV: '"production"'
            }
        }),
        new webpack.optimize.UglifyJsPlugin({
            sourceMap: true,
            compress: {
                warnings: false
            }
        }),
        new webpack.LoaderOptionsPlugin({
            minimize: true
        })
    ])
}

靜態資源緩存

處理:chunkFilename: [name].[hash].js
描述:每次構建時,在文件名上生成惟一的hash。
瀏覽器的緩存機制,瀏覽器會將網站下的靜態資源文件(.css .js .html)緩存下載,以減小網絡請求和下載(http狀態是304)。但也會引發很頭疼的問題,在服務器端,當文件內容改變時,刷新瀏覽器端頁面卻沒有被獲取到最新的更改。這時候就須要強制清除緩存,從新加載頁面。使用webpack提供的hash值命名文件,能夠防止在文件更新後,客戶端調用緩存的問題。vue

第三方類庫打包

處理:verdors 和 CommonsChunkPlugin
描述:項目中常常會用到第三方類庫,好比jquery,lodash,bootstrap等。通常配置好entry和output後,每次build都要把依賴的資源從新打包一次。這樣很費時間,另外對更新也不太友好。經過在entry.verdors:['lodash','jquery']添加須要引入的第三方類庫,和plugins:[new webpack.optimize.CommonsChunkPlugin({name:'vendors'})],把原來打包到main.js文件中的類庫,統一打包在verdors.js文件中,而且還能夠繼續在其餘腳本文件中使用import獲取引用node

在項目構建的過程當中,會先把打包vendors指明的第三方類庫打包。好比在個人項目裏第三方依賴有lodash、vue、vue-router、vue-resource、element-ui,在剛開始的打包進度裏,總共有五個模塊須要打包。jquery

模塊別名

處理:alias 配置模塊
描述:項目中常常須要用到一個或多個公用的文件夾,好比components(組件),service等。直接使用文件的相對路徑引入,在文件位置發生時要從新修改一遍文件引入路徑。另外在一些目錄結構比較深的腳本里引入公共組件文件時,經常的'../../../'前綴會讓代碼看起來很凌亂,也不容易維護。
使用文件別名,就能夠解決文件引入路徑過深,文件更改時須要從新修改路徑的問題。webpack

區分開發和產品模式

處理:process.env.NODE_ENV
描述:在項目package.json中配置scripts腳本命令,以下web

{
  "name": "demo",
  "description": "A demo project",
  "version": "1.0.0",
  "author": "",
  "private": true,
  "scripts": {
    "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
    "build": "cross-env NODE_ENV=production webpack --colors --progress --display-modules"
  },
  "dependencies": {
    ...
  },
  "devDependencies": {
    ...
  }
}

而後就能夠根據不一樣的進程環境區分開發代碼和產品代碼,好比在開發模式時混入一些默認數據,帳號密碼,開發API等等。每次構建的時候根據不一樣的環境將環境下的數據打包到代碼裏。vue-router

let baseUrl, defaultAccount = {
    username:'',
    password:''
};

if (process.env.NODE_ENV == 'production') {
    //線上版本接口地址
    baseUrl = '線上地址'
    
} else {
    defaultAccount.username = 'demo';  // 在線上模式不會將帳號密碼打包進去
    defaultAccount.password = '123456';
    baseUrl = '開發地址'
}

export {
    baseUrl,
    defaultAccount
}

加速代碼構建

處理:開啓多線程
描述:webpack對各種資源的加載,是須要配置不一樣的loader加載器獲取資源;測試過在模塊較少的時候打包速度就很是快,隨着項目越滾越大,構建速度會慢不少。element-ui

提高代碼壓縮

處理:UglifyJsParallelPlugin
描述:每次在build的過程當中,都會發現當打包進度到91%的時候就會停滯一下子。json

相關文章
相關標籤/搜索