webpack4配置vue開發(fā)環(huán)境

本文總結Webpack4常見的配置翘簇。
1设捐、基礎配置(讓項目跑起來)
2、webpack處理css
3思恐、webpack處理sass文件
4荒吏、webpack為sass添加source map
5敛惊、webpack為css添加CSS3前綴
6渊鞋、抽離樣式表為單獨的css文件并打版本號
7绰更、webpack壓縮CSS
8、webpack壓縮js
9锡宋、webpack添加頁面模板
10儡湾、webpack清理打包后的dist目錄
11、webpack處理圖片
12执俩、webpack壓縮圖片
13徐钠、webpack把小圖片轉為base64
14、webpack處理文字
15役首、webpack配置js使用sourceMap
16尝丐、webpack開啟熱更新和代理配置
17、webpack啟用babel轉碼
18衡奥、alias對文件路徑優(yōu)化
19爹袁、使用happypack并發(fā)執(zhí)行任務
案例中自帶不細說:
1、定義全局變量
2矮固、合并提取webpack公共配置
3失息、使用靜態(tài)資源路徑publicPath(CDN)

1、基礎配置

讓項目跑起來
項目初始化:
npm init
安裝webpack档址、vue盹兢、與vue-loader:
npm i webpack vue vue-loader -D
webpack4 已經啟用webpack-cli :
npm i webpack-cli -s -d
解析.vue文件,與內聯(lián)css:
npm i css-loader vue-template-compiler -D
并按照下面目錄構建項目

image.png

app.vue

<template>
    <div> luckfine </div>
</template>
<script>
    export default {
        data () {
            //text: 'luckfine'
        }
    }
</script>
<style>
</style>

index.js

// index.js
import Vue from 'vue'
import App from '../components/app.vue'

const root = document.createElement('div')
document.body.appendChild(root)

new Vue({
    render: (h) => h(App)
}).$mount(root)

webpack.js

// webpack.js
const path = require('path')
const VueLoaderPlugin = require('vue-loader/lib/plugin');

module.exports = {
    entry:  path.join(__dirname, 'src/spa/index.js'),
    mode:'develop',
    output: {
        filename: 'bundle.js',
        path: path.join(__dirname, 'dist')
    },
    module: {
        rules: [
            {
                test: /.vue$/,
                loader: 'vue-loader'
            }
        ]
    },
    plugins:[
        new VueLoaderPlugin()
    ],
}

在package.json 文件里的scripts對象里面添加一個腳本:
(注意:webpack4中已經在啟動時用mode指定啟動環(huán)境)

 "scripts": {
    "build": "webpack --config webpack.config.js --mode=development"
  },
image.png

讓我們的spa項目先跑起來

npm install webpack-dev-server -s -d
npm install html-webpack-plugin -d -s
// webpack.config.js

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

module.exports = {
    entry:  path.join(__dirname, 'src/h5/pages/demo.js'),
    mode:'develop',
    output: {
        filename: 'bundle.js',
        path: path.join(__dirname, 'dist')
    },
    module: {
        rules: [
            {
                test: /.vue$/,
                loader: 'vue-loader'
            }
        ]
    },
    resolve: {
        extensions: [
          '.vue', '.js'
        ],
        modules: ["node_modules"],
        alias: {
          vue: 'vue/dist/vue.min.js',
          components: path.resolve(__dirname + '/src/components/'),
          '@': path.resolve('src')
        }
    },
    plugins:[
        new HtmlWebpackPlugin(),
        new VueLoaderPlugin()
    ],
    devServer: {
        historyApiFallback: {
          index: `/dist/h5/index.html`
        },
        host: '0.0.0.0',
        disableHostCheck: true
    }
}

添加項目快捷啟動

"dev": "webpack-dev-server --inline --hot --mode=development",

npm run dev

image.png

項目已經跑起來了守伸,開始webpack的配置

2绎秒、webpack處理css

npm i -D css-loader style-loader

//  webpack.config.js
    module: {
        rules: [
            {
                test: /.vue$/,
                loader: 'vue-loader'
            },
            {
                test: /\.css/,
                use: ['style-loader', 'css-loader'] // use的順序從右往左
            }
        ]
    },
image.png

3、webpack處理sass文件

npm install sass-loader node-sass -D

    module: {
        rules: [
            {
                test: /.vue$/,
                loader: 'vue-loader'
            },
            {
                test: /\.(sc|sa|c)ss$/,
                use: ['style-loader', 'css-loader', 'sass-loader'] // use的順序從右往左
            }
        ]
    },
image.png

4尼摹、webpack為sass添加source map

image.png
            {
                test: /\.(sc|sa|c)ss$/,
                use: [
                    {
                        loader: 'style-loader'
                    },
                    {
                        loader: 'css-loader',
                        options: {
                            sourceMap: true
                        }
                    },
                    {
                        loader: 'sass-loader',
                        options: {
                            sourceMap: true
                        }
                    }
                ]
            }

添加后


image.png

5见芹、webpack為css添加CSS3前綴

npm i -D postcss-loader autoprefixer postcss 

在剛才的index.css 加上display: flex;
根目錄新建一個postcss.config.js

module.exports = {
  plugins: [
    require('precss'),
    require('autoprefixer')
  ]
}
    module: {
        rules: [
            {
                test: /.vue$/,
                loader: 'vue-loader'
            },
            {
                test: /\.(sc|sa|c)ss$/,
                use: [
                    {
                        loader: 'style-loader'
                    },
                    {
                        loader: 'css-loader',
                        options: {
                            sourceMap: true
                        }
                    },
                    {
                        loader: 'postcss-loader'
                    },
                    {
                        loader: 'sass-loader',
                        options: {
                            sourceMap: true
                        }
                    }
                ]
            }
        ]
    },
image.png

6校辩、抽離樣式表為單獨的css文件并打版本號

npm install webpack-merge -s -d
npm i -D mini-css-extract-plugin
//webpack.prod.config.js
const merge = require('webpack-merge')
const webpack = require('webpack');
const baseConfig = require('./webpack.config.js')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const devMode = process.env.NODE_ENV !== 'production'


module.exports = merge(baseConfig, {
    module: {
        rules: [
            {
                test: /\.(sc|sa|c)ss$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    {
                        loader: 'style-loader'
                    },
                    {
                        loader: 'css-loader',
                        options: {
                            sourceMap: true
                        }
                    },
                    {
                        loader: 'postcss-loader'
                    },
                    {
                        loader: 'sass-loader',
                        options: {
                            sourceMap: true
                        }
                    }
                ]
            }
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: devMode ? '[name].css' : '[name].[hash:8].css', 
            chunkFilename: devMode ? '[id].css': '[id].[hash:8].css'
        })
    ]
})

"dist": "webpack --config webpack.prod.config.js --mode=production",

image.png

7、webpack壓縮CSS

npm i -D optimize-css-assets-webpack-plugin
    optimization: {
        minimizer: [
            // 壓縮CSS
            new OptimizeCSSAssertsPlugin({})
        ]
    },
image.png

8辆童、webpack壓縮js

npm i -D uglifyjs-webpack-plugin
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')

    optimization: {
        minimizer: [
            // 壓縮CSS
            new OptimizeCSSAssertsPlugin({}),
            // 壓縮JS
            new UglifyJsPlugin({
                // 有很多可以配置
                cache: true,
                parallel: true,
                sourceMap: true,
                uglifyOptions: {
                     // 在UglifyJs刪除沒有用到的代碼時不輸出警告
                    warnings: false,
                    output: {
                        // 刪除所有的注釋
                        comments: false,
                        // 最緊湊的輸出
                        beautify: false
                    },
                    compress: {
                        // 刪除所有的 `console` 語句
                        // 還可以兼容ie瀏覽器
                        drop_console: true,
                        // 內嵌定義了但是只用到一次的變量
                        collapse_vars: true,
                        // 提取出出現(xiàn)多次但是沒有定義成變量去引用的靜態(tài)值
                        reduce_vars: true,
                    }
                }
            })
        ]
    },
image.png

Uglify-js不支持es6語法宜咒,請使用terser插件, 于是我們更改使用terser插件試試, 其實你繼續(xù)用uglifyjs-webpack-plugin也可以, 只需要配合babel先轉下。

const TerserPlugin = require('terser-webpack-plugin');
    optimization: {
        minimizer: [
            // 壓縮CSS
            new OptimizeCSSAssertsPlugin({}),
            // 壓縮JS
            new TerserPlugin({
                cache: true,
                parallel: true,
                sourceMap: true
            })
        ]
    },

更多配置見官網terser-webpack-plugin把鉴。

image.png

9故黑、webpack添加頁面模板

html-webpack-plugin插件可以把js/css注入到一個模板文件, 所以不需要再手動更改引用。
創(chuàng)建一個模板

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
    <meta name="format-detection" content="telephone=no">
    <title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
    
</body>
</html>
// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin')

plugins: [
    // 打包模板
        new HtmlWebpackPlugin({
            inject: true,
            hash: true,
            cache: true,
            chunksSortMode: 'none',
            title: '頁面模板', // 可以由外面?zhèn)魅?            filename: 'index.html', // 默認index.html
            template: 'src/spa/index.html',
            minify: {
                collapseWhitespace: true,
                removeComments: true,
                removeRedundantAttributes: true,
                removeScriptTypeAttributes: true,
                removeStyleLinkTypeAttributes: true
            }
        }),
],

image.png

10庭砍、webpack清理打包后的dist目錄

npm i -D clean-webpack-plugin

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

plugins:[
        new CleanWebpackPlugin()
]

11场晶、webpack處理圖片

            {
                test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            limit: 1,
                            name: '[name].[hash].[ext]'
                        },
                    },
                ]
            }
image.png

12、webpack壓縮圖片

npm i -D image-webpack-loader

            {
                test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            limit: 1,
                            name: '[name].[hash].[ext]'
                        },
                    },
                    {
                        loader: 'image-webpack-loader',
                        options: {
                          mozjpeg: {
                            progressive: true,
                            quality: 65
                          },
                          // optipng.enabled: false will disable optipng
                          optipng: {
                            enabled: false,
                          },
                          pngquant: {
                            quality: '65-90',
                            speed: 4
                          },
                          gifsicle: {
                            interlaced: false,
                          },
                          // the webp option will enable WEBP
                          webp: {
                            quality: 75
                          }
                        }
                    }
                ]
            }

目前圖片112kb,壓縮后31kb

13怠缸、webpack把圖片轉為base64

npm i -D url-loader

            {
                test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
                use: [
                    {
                        loader: 'url-loader',
                        options: {
                            // 具體配置見插件官網
                            limit: 10000,
                            name: '[name]-[hash:5].[ext]'
                        },
                    },
                    {
                        loader: 'image-webpack-loader',
                        options: {
                          mozjpeg: {
                            progressive: true,
                            quality: 65
                          },
                          // optipng.enabled: false will disable optipng
                          optipng: {
                            enabled: false,
                          },
                          pngquant: {
                            quality: '65-90',
                            speed: 4
                          },
                          gifsicle: {
                            interlaced: false,
                          },
                          // the webp option will enable WEBP
                          webp: {
                            quality: 75
                          }
                        }
                    }
                ]
            },
image.png

14诗轻、webpack處理文字

{
    test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
    loader: 'url-loader',
    options: {
        // 文件大小小于limit參數,url-loader將會把文件轉為DataUR
        limit: 10000,
        name: '[name]-[hash:5].[ext]',
        output: 'fonts/'
    }
},

15揭北、webpack配置js使用sourceMap

devtool: 'inline-source-map'

16扳炬、webpack開啟熱更新和代理配置

    devServer: {
        clientLogLevel: 'warning', // 輸出日志級別
        hot: true, // 啟用熱更新
        contentBase: path.resolve(__dirname, 'dist'), // 告訴服務器從哪里提供內容
        publicPath: '/', // 此路徑下的打包文件可在瀏覽器下訪問
        compress: true, // 啟用gzip壓縮
        // publicPath: './',
        disableHostCheck: true,
        host: '0.0.0.0',
        port: 8080,
        open: true, // 自動打開瀏覽器
        overlay: { // 出現(xiàn)錯誤或者警告時候是否覆蓋頁面線上錯誤信息
            warnings: true,
            errors: true
        },
        quiet: true,
        watchOptions: { // 監(jiān)控文件相關配置
            poll: true,
            ignored: /node_modules/, // 忽略監(jiān)控的文件夾, 正則
            aggregateTimeout: 300, // 默認值, 當你連續(xù)改動時候, webpack可以設置構建延遲時間(防抖)
        }
    },

webpack啟用babel轉碼
npm i -D babel-loader @babel/core @babel/preset-env @babel/runtime @babel/plugin-transform-runtime

// 編譯js
{
    test: /\.js$/,
    exclude: /(node_modules|bower_components)/,
    use: {
        loader: 'babel-loader?cacheDirectory', // 通過cacheDirectory選項開啟支持緩存
        options: {
          presets: ['@babel/preset-env']
        }
    }
},

添加.babelrc文件


// 僅供參考
{
    "presets": [
      [
        "@babel/preset-env"
      ]
    ],
    "plugins": [
      [
        "@babel/plugin-transform-runtime",
        {
          "corejs": false,
          "helpers": true,
          "regenerator": true,
          "useESModules": false,
          "absoluteRuntime": "@babel/runtime"
        }
      ]
    ]
  }

18、alias對文件路徑優(yōu)化

配置alias方便路徑的檢索效率搔体。 加快模塊的查找速度

   resolve: {
        extensions: ['.vue', '.js'],
        modules: ['node_modules'],
        alias: {
          components: __dirname + '/src/components/',
          assets: __dirname + '/src/assets/'
        }
    },

19恨樟、使用happypack并發(fā)執(zhí)行任務

在 Loader 配置中,所有文件的處理都交給了 happypack/loader 去處理疚俱,使用緊跟其后的 querystring ?id=babel 去告訴 happypack/loader 去選擇哪個 HappyPack 實例去處理文件劝术。


const HappyPack = require('HappyPack')
const os = require('os');
const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });

{
    test: /\.js$/,
    exclude: /(node_modules|bower_components)/,
    use: [
        {
            // 一個loader對應一個id
            loader: "happypack/loader?id=luckfine"
        }
    ]
},

 
new HappyPack({
      // 用唯一的標識符id,來代表當前的HappyPack是用來處理一類特定的文件
      id:'luckfine',
        //如何處理  用法和loader 的配置一樣
      loaders: [{
        loader: 'babel-loader?cacheDirectory=true',
      }],
      //共享進程池
      threadPool: happyThreadPool,
      //允許 HappyPack 輸出日志
      verbose: true,
}),

本文源碼:https://github.com/luckFine/vue-webpack.git
可手抖star呆奕,歡迎有遺漏補充养晋。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市梁钾,隨后出現(xiàn)的幾起案子绳泉,更是在濱河造成了極大的恐慌,老刑警劉巖陈轿,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件圈纺,死亡現(xiàn)場離奇詭異,居然都是意外死亡麦射,警方通過查閱死者的電腦和手機蛾娶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來潜秋,“玉大人蛔琅,你說我怎么就攤上這事【海” “怎么了罗售?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵辜窑,是天一觀的道長。 經常有香客問我寨躁,道長穆碎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任职恳,我火速辦了婚禮所禀,結果婚禮上,老公的妹妹穿的比我還像新娘放钦。我一直安慰自己色徘,他們只是感情好,可當我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布操禀。 她就那樣靜靜地躺著褂策,像睡著了一般。 火紅的嫁衣襯著肌膚如雪颓屑。 梳的紋絲不亂的頭發(fā)上斤寂,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天,我揣著相機與錄音邢锯,去河邊找鬼扬蕊。 笑死,一個胖子當著我的面吹牛丹擎,可吹牛的內容都是我干的。 我是一名探鬼主播歇父,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼蒂培,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了榜苫?” 一聲冷哼從身側響起护戳,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎垂睬,沒想到半個月后媳荒,有當地人在樹林里發(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡驹饺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年钳枕,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片赏壹。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡鱼炒,死狀恐怖,靈堂內的尸體忽然破棺而出蝌借,到底是詐尸還是另有隱情昔瞧,我是刑警寧澤指蚁,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站自晰,受9級特大地震影響凝化,放射性物質發(fā)生泄漏。R本人自食惡果不足惜酬荞,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一缘圈、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧袜蚕,春花似錦糟把、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至凿傅,卻和暖如春缠犀,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背聪舒。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工辨液, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人箱残。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓滔迈,卻偏偏與公主長得像,于是被迫代替她去往敵國和親被辑。 傳聞我的和親對象是個殘疾皇子燎悍,可洞房花燭夜當晚...
    茶點故事閱讀 42,834評論 2 345