分享18個webpack插件,你千萬要收藏好,留備用


來源 | https : //github.com/Michael-lzg/

何爲插件(Plugin)?專一處理 webpack 在編譯過程當中的某個特定的任務的功能模塊,能夠稱爲插件。
插件是一個擴展器,它豐富了 webpack 自己,針對的是loader結束後, webpack 打包的整個過程,它並不直接操做文件,而是基於事件機制工做,會監聽webpack 打包過程當中的某些實例,執行普遍的任務。

插件的特色

  • 是一個獨立的模塊javascript

  • 模塊對外暴露一個js 函數css

  • 函數的原型(原型)上定義了一個注入編譯對象的適用方法適用  函數中須要有經過編譯對象掛載的  的WebPack  事件鉤子,鉤子的回調中能拿到當前編譯的編譯對象,若是是異步編譯插件的話能夠拿到些回調html

  • 完成自定義子編譯流程並處理complition對象的內部數據前端

  • 若是異步編譯插件的話,數據處理完成後執行callback。vue

下面介紹18個經常使用的 webpack 插件。

一、HotModuleReplacementPlugin

的熱更新是依賴於   webpack  -dev-server,另外是在打包文件更改時更新打包文件或者從新加載刷新整個頁面,HRM是隻更新修改的部分。
HotModuleReplacementPlugin是 webpack 模塊自帶的,因此 ♡webpack 後,在插件配置項中直接使用便可。
  
    
  
  
   
   
            
   
   
    
      
    
    
     
     
              
     
     
const webpack = require('webpack')
plugins: [ new webpack.HotModuleReplacementPlugin(), // 熱更新插件]

二、html -webpack-plugin

生成 html 文件。將webpack中條目配置的相關入口大塊和extract-text-webpack-plugin的 css 樣式插入到該插件提供的模板或模板內容配置項指定的內容基礎上生成一個 html 文件,具體插入方式是將樣式連接插入到head元素中,腳本插入到head或者body中。
  
    
  
  
   
   
            
   
   
    
      
    
    
     
     
              
     
     
const htmlWebpackPlugin = require('html-webpack-plugin')
plugins: [ newhtmlWebpackPlugin({ filename: 'index.html', template: path.join(__dirname, '/index.html'), minify: { // 壓縮html文件 removeComments: true, // 移除html中的註釋 collapseWhitespace: true, // 刪除空白符與換行符 minifycss: true, // 壓縮內聯css }, inject: true, }),]
注入有四個選項值
  • true:默認值,script標籤位於html文件的body底部java

  • body:script標籤置於html文件的body底部(同true)node

  • head:script標籤放在head標籤內react

  • false:不插入生成的js文件,只是單純的生成一個html文件jquery

多頁應用打包
有時,咱們的應用不必定是一個單頁應用,或者一個多頁應用,那麼如何使用webpack進行打包呢。
  
    
  
  
   
   
            
   
   
    
      
    
    
     
     
              
     
     
const path = require('path')const HtmlWebpackPlugin = require('html-webpack-plugin')module.exports = { entry: { index: './src/index.js', login: './src/login.js', }, output: { path: path.resolve(__dirname, 'dist'), filename: '[name].[hash:6].js', }, //... plugins: [ new HtmlWebpackPlugin({ template: './public/index.html', filename: 'index.html', //打包後的文件名 }), new HtmlWebpackPlugin({ template: './public/login.html', filename: 'login.html', //打包後的文件名 }), ],}
若是須要配置多個HtmlWebpackPlugin,則文件名不可更改,不然生成的都是index.html。
可是有個問題,index.html和login.html會發現,都同時約會了index.f7d21a。 js   和login.f7d21a。 js ,一般這不是咱們想要的,咱們但願index.html停止日期index.f7d21a。 js ,login.html只保留login.f7d21a。 js
HtmlWebpackPlugin提供了一個塊的參數,能夠接受一個數組,配置此參數惟一的插入數組中指定的 js 日期到html文件中。
  
    
  
  
   
   
            
   
   
    
      
    
    
     
     
              
     
     
module.exports = { //... plugins: [ new HtmlWebpackPlugin({ template: './public/index.html', filename: 'index.html', //打包後的文件名 chunks: ['index'], }), new HtmlWebpackPlugin({ template: './public/login.html', filename: 'login.html', //打包後的文件名 chunks: ['login'], }), ],}
這樣執行   npm  run build,能夠看到index.html中惟一約會了index的js文件,而login.html中也只有約會了login的js文件。

三、clean-webpack-plugin

clean-webpack-plugin用於在打包前清理上一次項目生成的捆綁文件,它會根據output.path自動清理文件夾;這個插件在生產環境用的頻率很是高,由於生產環境常常會經過hash生成不少bundle文件,若是不進行清理的話每次都會生成新的,致使文件夾很是龐大。
  
    
  
  
   
   
            
   
   
    
      
    
    
     
     
              
     
     
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
plugins: [ new HtmlWebpackPlugin({ template: path.join(__dirname, '/index.html'), }), new CleanWebpackPlugin(), // 所要清理的文件夾名稱]

四、提取文本Webpack插件

CSS 成生文件,而非內聯。該插件的主要是爲了抽離 CSS 樣式,防止將樣式打包在JS中引發頁面樣式加載錯亂的現象
  
    
  
  
   
   
            
   
   
    
      
    
    
     
     
              
     
     
const ExtractTextPlugin = require('extract-text-webpack-plugin')
plugins: [ // 將css分離到/dist文件夾下的css文件夾中的index.css new ExtractTextPlugin('css/index.css'),]

五、迷你CSS提取插件

將CSS提取爲獨立的文件的插件,對每一個包含css的js文件都會建立一個CSS文件,支持按需加載css和sourceMap。只能用在webpack4中,對比另外一個插件extract-text-webpack-plugin有如下特色:
  • 初步加載webpack

  • 不重複編譯,性能更好

  • 更容易使用

  • 只針對CSS

這個插件應該只用在生產環境配置,而且在裝載機上鍊中不使用style-loader,並且這個插件暫時不支持HMR
  
    
  
  
   
   
            
   
   
    
      
    
    
     
     
              
     
     
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = { module: { rules: [ { test: /\.(le|c)ss$/, use: [ { loader: MiniCssExtractPlugin.loader, options: { publicPath: '../', }, }, 'css-loader', 'postcss-loader', 'less-loader', ], }, ], }, plugins: [ new MiniCssExtractPlugin({ filename: 'css/[name].[contenthash:8].css', chunkFilename: 'css/[id].[contenthash:8].css', }), ],}

六、purifycss-webpack

有時候咱們css寫更多了或者重複了,由此形成了多餘的 代碼 ,咱們但願在生產環境進行移除。
  
    
  
  
   
   
            
   
   
    
      
    
    
     
     
              
     
     
const path = require('path')const PurifyCssWebpack = require('purifycss-webpack') // 引入PurifyCssWebpack插件const glob = require('glob') // 引入glob模塊,用於掃描所有html文件中所引用的css
module.exports = merge(common, { plugins: [ new PurifyCssWebpack({ paths: glob.sync(path.join(__dirname, 'src/*.html')), }), ],})

七、優化CSS資產Webpack插件

咱們但願串聯css打包後的體積,能夠用到Optimiz-css-assets-webpack-plugin。
  
    
  
  
   
   
            
   
   
    
      
    
    
     
     
              
     
     
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin") // 壓縮css代碼
optimization: { minimizer: [ // 壓縮css new OptimizeCSSAssetsPlugin({}) ] }

八、UglifyJsPlugin

uglifyJsPlugin是   vue  -cli默認使用的壓縮 代碼 方式,用於對js文件進行壓縮,從而插入js文件的大小,加速加載速度。
它使用的是單線程壓縮 代碼 ,打包時間較慢,因此能夠在開發環境將其關閉,生產環境部署時再把它打開。
  
    
  
  
   
   
            
   
   
    
      
    
    
     
     
              
     
     
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
plugins: [ new UglifyJsPlugin({ uglifyOptions: { compress: { warnings: false } }, sourceMap: true, //是否啓用文件緩存 parallel: true //使用多進程並行運行來提升構建速度 })

九、ParallelUglifyPlugin

開啓多個子進程,把對多個文件壓縮的工做分別給多個子進程去完成,每一個子進程其實仍是經過UglifyJS去壓縮 代碼 ,可是變成了並行執行。
  
    
  
  
   
   
            
   
   
    
      
    
    
     
     
              
     
     
const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin')
plugins: [ new ParallelUglifyPlugin({ //cacheDir 用於配置緩存存放的目錄路徑。 cacheDir: '.cache/', sourceMap: true, uglifyJS: { output: { comments: false, }, compress: { warnings: false, }, }, }),]

十、terser-webpack-plugin

Webpack4.0默認是使用terser-webpack-plugin這個壓縮插件,在此以前是使用uglifyjs-webpack-plugin,它們的區別是對ES6的壓縮不是很好,同時咱們能夠開啓parallel參數,使用多進行壓縮,加快壓縮。
  
    
  
  
   
   
            
   
   
    
      
    
    
     
     
              
     
     
const TerserPlugin = require('terser-webpack-plugin') // 壓縮js代碼
optimization: { minimizer: [ new TerserPlugin({ parallel: 4, // 開啓幾個進程來處理壓縮,默認是 os.cpus().length - 1 cache: true, // 是否緩存 sourceMap: false, }), ]}

十一、NoErrorsPlugin

報錯但不退出webpack進程。編譯出現錯誤時,使用NoEmitOnErrorsPlugin來跳過輸出階段。這樣能夠確保輸出資源不會包含錯誤。
  
    
  
  
   
   
            
   
   
    
      
    
    
     
     
              
     
     
plugins: [new webpack.NoEmitOnErrorsPlugin()]

十二、壓縮webpack插件

全部現代 瀏覽器 都支持gzip壓縮,啓用gzip壓縮可擴展和擴展傳輸資源大小,從而延長資源下載時間,減小首次白屏時間,提高用戶體驗。
gzip對基於文本格式文件的壓縮效果最好(如:CSS, JavaScript 和HTML),在壓縮壓縮文件時每每可實現高達70-90%的壓縮率,對已經壓縮過的資源(如:圖片)進行gzip壓縮處理,效果很很差。
  
    
  
  
   
   
            
   
   
    
      
    
    
     
     
              
     
     
const CompressionPlugin = require('compression-webpack-plugin')
plugins: [ new CompressionPlugin({ // gzip壓縮配置 test: /\.js$|\.html$|\.css/, // 匹配文件名 threshold: 10240, // 對超過10kb的數據進行壓縮 deleteOriginalAssets: false, // 是否刪除原文件 }),]
固然,這個方法還須要預先配置支持。

1三、定義插件

咱們能夠經過DefinePlugin能夠定義一些類別的變量,咱們能夠在模塊之間直接使用這些變量,無需做任何聲明,DefinePlugin是webpack自帶的插件。
  
    
  
  
   
   
            
   
   
    
      
    
    
     
     
              
     
     
plugins: [ new webpack.DefinePlugin({ DESCRIPTION: 'This Is The Test Text.', }),]
// 直接引用console.log(DESCRIPTION)

1四、ProvidePlugin

任什麼時候候,當標識符被視爲未賦值的變量時,模塊就會自動被加載,而且標識符會被這個模塊輸出的內容所賦值。這是webpack自帶的插件。
  
    
  
  
   
   
            
   
   
    
      
    
    
     
     
              
     
     
module.exports = { resolve: { alias: { jquery: './lib/jquery', }, }, plugins: [ //提供全局的變量,在模塊中使用無需用require引入 new webpack.ProvidePlugin({ $: 'jquery',react: 'react', }), ],}

1五、DLL插件

這是在一個額外的獨立的webpack設置中建立一個只有dll的bundle(dll-only-bundle)。這個插件會生成一個清單manifest.json的文件,這個文件是用來讓DLLReferencePlugin映射到相關的依賴上去的。
使用步驟以下:
1,在build下建立webpack.dll.config.js
  
    
  
  
   
   
            
   
   
    
      
    
    
     
     
              
     
     
const path = require('path')const webpack = require('webpack')module.exports = { entry: { vendor: [ 'vue-router', 'vuex', 'vue/dist/vue.common.js', 'vue/dist/vue.js', 'vue-loader/lib/component-normalizer.js', 'vue', 'axios', 'echarts', ], }, output: { path: path.resolve('./dist'), filename: '[name].dll.js', library: '[name]_library', }, plugins: [ new webpack.DllPlugin({ path: path.resolve('./dist', '[name]-manifest.json'), name: '[name]_library', }), // 建議加上代碼壓縮插件,不然dll包會比較大。 new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false, }, }), ],}
2,在webpack.prod.conf.js的插件後面加入配置
  
    
  
  
   
   
            
   
   
    
      
    
    
     
     
              
     
     
new webpack.DllReferencePlugin({ manifest: require('../dist/vendor-manifest.json'),})
3,package.json文件中添加快捷命令(build:dll)
  
    
  
  
   
   
            
   
   
    
      
    
    
     
     
              
     
     
"scripts": { "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", "start": "npm run dev", "lint": "eslint --ext .js,.vue src", "build": "node build/build.js", "build:dll": "webpack --config build/webpack.dll.conf.js" }
生產環境打包的時候先 npm 運行build:dll命令在打包目錄下生成vendor-manifest.json文件與vendor.dll.js文件。而後 npm 運行build生產其餘文件。
4,根目錄下的入口index.html加入引用
  
    
  
  
   
   
            
   
   
    
      
    
    
     
     
              
     
     
<script type="text/JavaScript" src="./vendor.dll.js"></script>

1六、快樂包

對文件加載器,URL加載器支持的不友好,因此不建議該加載程序使用。
1,HappyPack插件安裝
  
    
  
  
   
   
            
   
   
    
      
    
    
     
     
              
     
     
npm i -D happypack
2,webpack.base.conf.js文件對module.rules進行配置
  
    
  
  
   
   
            
   
   
    
      
    
    
     
     
              
     
     
module: { rules: [ { test: /\.js$/, use: ['happypack/loader?id=babel'], include: [resolve('src'), resolve('test')], exclude: path.resolve(__dirname, 'node_modules'), }, { test: /\.vue$/, use: ['happypack/loader?id=vue'], }, ]}
三、在生產環境中webpack.prod.conf.js文件進行配置
  
    
  
  
   
   
            
   
   
    
      
    
    
     
     
              
     
     
const HappyPack = require('happypack')// 構造出共享進程池,在進程池中包含5個子進程const HappyPackThreadPool = HappyPack.ThreadPool({ size: 5 })plugins: [ new HappyPack({ // 用惟一的標識符id,來表明當前的HappyPack是用來處理一類特定的文件 id: 'babel', // 如何處理.js文件,用法和Loader配置中同樣 loaders: ['babel-loader?cacheDirectory'], threadPool: HappyPackThreadPool, }), new HappyPack({ id: 'vue', // 用惟一的標識符id,來表明當前的HappyPack是用來處理一類特定的文件 loaders: [ { loader: 'vue-loader', options: vueLoaderConfig, }, ], threadPool: HappyPackThreadPool, }),]
注意,當項目較小時,多線程捆反而增長捆速度變慢。

1七、複製webpack插件

咱們在public / index.html中約會了靜態資源,可是打包的時候webpack並不會幫咱們複製到dist目錄,所以copy-webpack-plugin就能夠很好地幫我作副本的工做了。
  
    
  
  
   
   
            
   
   
    
      
    
    
     
     
              
     
     
const CopyWebpackPlugin = require('copy-webpack-plugin')module.exports = { plugins: [ new CopyWebpackPlugin({ patterns: [ { from: 'public/js/*.js', to: path.resolve(__dirname, 'dist', 'js'), flatten: true, }, ], }), ],}

1八、忽略插件

這是webpack內置插件,它的做用是:忽略第三方包指定目錄,讓這些指定目錄不要被打包進去。
例如咱們要使用一下這個第三方依賴庫,該庫主要是對時間進行格式化,並支持多種國家語言。雖然我設置了語言爲中文,可是在打包的時候,是替換全部語言都打包進去的。這樣就致使包很大,打包速度又慢。進行,咱們能夠用IgnorePlugin忽略指定目錄,從而使打包變快,文件變小。
  
    
  
  
   
   
            
   
   
    
      
    
    
     
     
              
     
     
const Webpack = require('webpack')plugins: [ //moment這個庫中,若是引用了./locale/目錄的內容,就忽略掉,不會打包進去 new Webpack.IgnorePlugin(/\.\/locale/, /moment/),]
咱們雖然按照上面的方法忽略了包含'./locale/'該變量路徑的文件目錄,可是也使用咱們使用的時候不能顯示中文語言了,因此這個時候能夠手動發佈中文語言的目錄。
  
    
  
  
   
   
            
   
   
    
      
    
    
     
     
              
     
     
import moment from 'moment'
//手動引入所須要的語言包import 'moment/locale/zh-cn'
moment.locale('zh-cn')
let r = moment().endOf('day').fromNow()console.log(r)
本文完~

本文分享自微信公衆號 - web前端開發(web_qdkf)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索