溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Angular10怎么配置webpack打包

發布時間:2021-04-12 11:04:04 來源:億速云 閱讀:478 作者:小新 欄目:web開發

小編給大家分享一下Angular10怎么配置webpack打包,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

對于 Angular 項目,推薦使用 angular-cli 創建打包項目 Angular 會默認幫我們配置。 但是有特殊的需求時就顯然不是很靈活,比如想分割一些較大的打包文件、分析每個打包文件組成,自定義webpack一些參數的時候就發現無從下手。 對許多項目的常見依賴項是日期庫moment.js 。 這包括使用語言環境的功能,但是,它大大增加了整體捆綁軟件的大小。這些都是需要我們優化的地方。

一、ngx-build-plus 建立額外配置


這里推薦一個工具庫ngx-build-plus,不需要改很多東西就能在現有項目進行集成。接下來教大家如何使用,具體詳情可以去github上找文檔。雖然官方文檔上只標注到了可用版本為9,但是Angular10也是可以使用的。

1. 使用CLI創建一個新的Angular項目

從零搭建Angular10項目

2. 添加ngx-build-plus: ng add ngx-build-plus

注意:如果要將其添加到projects文件夾中的特定子項目,請使用--project開關指向它:ng add ngx-build-plus --project getting-started

備注:這一步通過NPM安裝包,在Angular >= 7 and CLI >= 7版本中,讓您的項目使用自定義生成器的更新您的angular.jsonng serveng build。但是6版本中可能會出現安裝不成功,這時候請直接yarn add ngx-build-plus --dev,然后angular.json文件中更改以下兩處地方:

 "build": {
   - "builder": "@angular-devkit/build-angular:browser"
   + "builder": "ngx-build-plus:build"
   ...
 },
 "serve": {
  - "builder": "@angular-devkit/build-angular:dev-server"
   + "builder": "ngx-build-plus:dev-server"
   ...
 }

相關教程推薦:《angular教程》

3. 創建文件webpack.partial.js并添加到(子)項目的根目錄:

  const webpack = require('webpack');
  
  module.exports = {
      plugins: [
          new webpack.DefinePlugin({
              "VERSION": JSON.stringify("4711")
          })
      ]
  }

4. 在您的 app.component.ts中使用全局變量VERSION:

  import { Component } from '@angular/core';
  
  declare const VERSION: string;
  
  @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
  })
  export class AppComponent {
      title = 'Version: ' + VERSION;
  }

5. 使用--extra-webpack-config指向部分Webpack配置的開關啟動應用程序:

ng serve --extra-webpack-config webpack.partial.js -o

如果您的項目是基于CLI的子項目,請也使用該--project開關:

ng serve --project getting-started -o --extra-webpack-config webpack.partial.js

提示:考慮為此命令創建一個npm腳本。

6. 確保顯示了您的webpack配置所提供的版本。

Angular10怎么配置webpack打包有打印結果顯示就表示你的項目已經啟用了webpack.partial.js文件中的配置,下面就是在webpack.partial.js中補充我們需要的功能了,筆者主要集中在了兩大塊。

  1. 添加BundleAnalyzerPlugin,分析打包文件

  2. 第三方庫模塊分離 - optimization + splitChunks,分割較大的文件

下面分別描述

二、webpack-bundle-analyzer 打包文件分析工具


1.安裝

$ yarn add  webpack-bundle-analyzer --dev

2.配置

webpack.partial.js中的module.exports = webpackConfig這句話的上面增加

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
module.exports = {
  plugins: [
    new BundleAnalyzerPlugin({
      analyzerMode: 'static',
    }),
    new webpack.DefinePlugin({
      "VERSION": JSON.stringify("4711")
    })
  ]
}

3.運行

啟動服務:

生產環境查看:npm run build --report 或 正常build 即可啟動查看器

開發環境查看:webpack -p --progress 或啟動正常devServer服務即可啟動查看器!

4.結果

Angular10怎么配置webpack打包

5.該插件默認配置

new BundleAnalyzerPlugin({
      // openAnalyzer: true,
      // reportFilename: path.join(__dirname, 'report.html')
      //  可以是`server`,`static`或`disabled`。
      //  在`server`模式下,分析器將啟動HTTP服務器來顯示軟件包報告。
      //  在“靜態”模式下,會生成帶有報告的單個HTML文件。
      //  在`disabled`模式下,你可以使用這個插件來將`generateStatsFile`設置為`true`來生成Webpack Stats JSON文件。
      analyzerMode: 'static',
      //  將在“服務器”模式下使用的主機啟動HTTP服務器。
      // analyzerHost: '127.0.0.1',
      //  將在“服務器”模式下使用的端口啟動HTTP服務器。
      // analyzerPort: 8888,
      //  路徑捆綁,將在`static`模式下生成的報告文件。
      //  相對于捆綁輸出目錄。
      // reportFilename: 'report.html',
      //  模塊大小默認顯示在報告中。
      //  應該是`stat`,`parsed`或者`gzip`中的一個。
      //  有關更多信息,請參見“定義”一節。
      // defaultSizes: 'parsed',
      //  在默認瀏覽器中自動打開報告
      // openAnalyzer: true,
      //  如果為true,則Webpack Stats JSON文件將在bundle輸出目錄中生成
      // generateStatsFile: false,
      //  如果`generateStatsFile`為`true`,將會生成Webpack Stats JSON文件的名字。
      //  相對于捆綁輸出目錄。
      // statsFilename: 'stats.json',
      //  stats.toJson()方法的選項。
      //  例如,您可以使用`source:false`選項排除統計文件中模塊的來源。
      //  在這里查看更多選項:https:  //github.com/webpack/webpack/blob/webpack-1/lib/Stats.js#L21
      // statsOptions: null,
      // logLevel: 'info' // 日志級別??梢允?#39;信息','警告','錯誤'或'沉默'。
    }),

模塊功能:能夠查看到你的文件打包壓縮后中真正的內容,找出那些模塊組成最大的大小,找到錯誤的模塊,優化它!最好的事情是它支持縮小捆綁!它解析它們以獲得實際大小的捆綁模塊。它也顯示他們的gzipped大??!

三、使用webpack把第三方庫模塊分離 - optimization + splitChunks


在 webpack4.x 中,我們使用 optimization.splitChunks 來分離公用的代碼塊。SplitChunks插件簡單的來說就是Webpack中一個提取或分離代碼的插件,主要作用是提取公共代碼,防止代碼被重復打包,拆分過大的js文件,合并零散的js文件。

這里說的分離,當然只是針對一些第三方庫(一般來自 node_modules),以及我們自己定義的工具庫(或公用方法)。

不知如何下手?首先,我們來看官網給的一份

1. 默認配置:

splitChunks: {
    chunks: "async",
    minSize: 30000,
    minChunks: 1,
    maxAsyncRequests: 5,
    maxInitialRequests: 3,
    automaticNameDelimiter: '~',
    name: true,
    cacheGroups: {
        vendors: {
            test: /[\\/]node_modules[\\/]/,
            priority: -10
        },
    default: {
            minChunks: 2,
            priority: -20,
            reuseExistingChunk: true
        }
    }
}

接著,我們再來看下它們的含義:

  • chunks: 該屬性值的數據類型可以是 字符串 或者 函數。如果是字符串,那它的值可能為 initial | async | all 三者之一。默認值的數據類型為 字符串,默認值為 async,但推薦用 all。它表示將哪種類型的模塊分離成新文件。字符串參數值的作用分別如下:

    • initial:表示對異步引入的模塊不處理

    • async:表示只處理異步模塊

    • all:無論同步還是異步,都會處理

  • minSize: 該屬性值的數據類型為數字。它表示將引用模塊分離成新代碼文件的最小體積,默認為 30000,單位為字節,即 30K(指min+gzip之前的體積)。這里的 30K 應該是最佳實踐,因為如果引用模塊小于 30K 就分離成一個新代碼文件,那頁面打開時,勢必會多增加一個請求。

  • maxSize: 把提取出來的模塊打包生成的文件大小不能超過maxSize值,如果超過了,要對其進行分割并打包生成新的文件。單位為字節,默認為0,表示不限制大小。

  • minChunks: 該屬性值的數據類型為數字。它表示將引用模塊如不同文件引用了多少次,才能分離生成新代碼文件。默認值為 1

  • maxAsyncRequests: 該屬性值的數據類型為數字,默認值為 5。它表示按需加載最大的并行請求數,針對異步。

  • maxInitialRequests: 該屬性值的數據類型為數字,默認值為 3。它表示單個入口文件最大的并行請求數,針對同步。

  • automaticNameDelimiter: 該屬性值的數據類型為字符串,默認值為。它表示分離后生成新代碼文件名稱的鏈接符,比如說 app1.js 和 app2.js 都引用了 utils.js 這個工具庫,那么,最后打包后分離生成的公用文件名可能是 xxapp1~app2.js 這樣的,即以 ~ 符號連接。

  • name: 該屬性值的數據類型可以是 布爾值 或者 函數(返回值為字符串),其中布爾值得為 true,此時,分離文件后生成的文件名將基于 cacheGroups 和 automaticNameDelimiter。如果設置為 false,則不會進行模塊分離。

  • cacheGroups: 該屬性值的數據類型為對象,它的值可以繼承 splitChunks.* 中的內容。如果 cacheGroups存在與 splitChunks.* 同名的屬性,則 cacheGroups 的屬性值則直接覆蓋 splitChunks.* 中設置的值。

  • test: 該屬性值的數據類型可以為 字符串 或 正則表達式,它規定了哪些文件目錄的模塊可以被分離生成新文件。

  • priority: 該屬性值的數據類型可以為數字,默認值為 0。它表示打包分離文件的優先

  • reuseExistingChunk: 該屬性值的數據類型可以為布爾值。它表示針對已經分離的模塊,不再重新分離。

2.分離第三方庫

要將第三方庫分離出來,我們需要調整配置文件,設置 chunks: 'all',即表示讓所有加載類型的模塊在某些條件下都能打包。

3.分離工具函數

打包中,我們發現,工具函數模塊(utils)的源碼被分別打包到了兩個文件中,這顯然是不對。之所以出現這種情況,是因為我們設置了 minSize: 30000,即分離成獨立文件的最小體積為 30K,而這里的 工具函數(utils.js)只有幾KB,所以,沒被分離成單獨的文件。

4.第三方庫合并打包并重命名

有的時候,我們希望將所有來自 node_modules 的第三方庫都打包到同一個文件中。顯然,上面的打包配置并沒有滿足這個條件。并且,我們還希望可以對打包后的文件名進行重命名。

要完成,只需要在 cacheGroups 設置 name 屬性即可。這里,筆者還把項目中使用到的moment、handsontable、angular庫單獨分離出來了。

// webpack.config.js
module.exports = {
  optimization: {
    splitChunks: {
      chunks: 'all',
      minSize: 30000,
      maxSize: 0,
      minChunks: 1,
      maxAsyncRequests: 5,
      maxInitialRequests: 3,
      automaticNameDelimiter: '~',
      name: true,
      cacheGroups: {
        moment: {
          name: 'moment',
          test: /[\\/]node_modules[\\/]moment[\\/]/,
          priority: -6						// 兩個cacheGroup.priority相同時,先定義的會先命中
        },
        handsontable: {
          name: 'handsontable',
          test: /[\\/]node_modules[\\/]handsontable[\\/]/,
          priority: -7
        },
        angular: {
          name: 'angular',
          test: /[\\/]node_modules[\\/]@angular[\\/]/,
          priority: -9
        },
       vendors: {
          name: 'vendors',
          test: /[\\/]node_modules[\\/]/,
          priority: -10
        },
        default: {
          name: 'default',
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true
        }
      }
    }
  }
}

5.SplitChunks插件配置選項

  • chunks選項,決定要提取那些模塊。

    默認是async:只提取異步加載的模塊出來打包到一個文件中。 異步加載的模塊:通過import('xxx')require(['xxx'],() =>{})加載的模塊。

    initial:提取同步加載和異步加載模塊,如果xxx在項目中異步加載了,也同步加載了,那么xxx這個模塊會被提取兩次,分別打包到不同的文件中。 同步加載的模塊:通過 import xxxrequire('xxx')加載的模塊。

    all:不管異步加載還是同步加載的模塊都提取出來,打包到一個文件中。

  • minSize選項:規定被提取的模塊在壓縮前的大小最小值,單位為字節,默認為30000,只有超過了30000字節才會被提取。

  • maxSize選項:把提取出來的模塊打包生成的文件大小不能超過maxSize值,如果超過了,要對其進行分割并打包生成新的文件。單位為字節,默認為0,表示不限制大小。

  • minChunks選項:表示要被提取的模塊最小被引用次數,引用次數超過或等于minChunks值,才能被提取。

  • maxAsyncRequests選項:最大的按需(異步)加載次數,默認為 6。

  • maxInitialRequests選項:打包后的入口文件加載時,還能同時加載js文件的數量(包括入口文件),默認為4。

  • 先說一下優先級 maxInitialRequests / maxAsyncRequests <maxSize<minSize。

  • automaticNameDelimiter選項:打包生成的js文件名的分割符,默認為~。

  • name選項:打包生成js文件的名稱。

  • cacheGroups選項,核心重點,配置提取模塊的方案。里面每一項代表一個提取模塊的方案。下面是cacheGroups每項中特有的選項,其余選項和外面一致,若cacheGroups每項中有,就按配置的,沒有就使用外面配置的。

  • test選項:用來匹配要提取的模塊的資源路徑或名稱。值是正則或函數。

  • priority選項:方案的優先級,值越大表示提取模塊時優先采用此方案。默認值為0。

  • reuseExistingChunk選項:true/false。為true時,如果當前要提取的模塊,在已經在打包生成的js文件中存在,則將重用該模塊,而不是把當前要提取的模塊打包生成新的js文件。

  • enforce選項:true/false。為true時,忽略minSize,minChunks,maxAsyncRequestsmaxInitialRequests外面選項

四、HtmlWebpackPlugin


HtmlWebpackPlugin簡化了HTML文件的創建,以便為你的webpack包提供服務。這對于在文件名中包含每次會隨著編譯而發生變化哈希的 webpack bundle 尤其有用。 你可以讓插件為你生成一個HTML文件,這個插件有兩個重要作用。

  1. 創建HTML頁面文件到你的輸出目錄

  2. 將webpack打包后的chunk自動引入到這個HTML中

1.安裝

npm install --save-dev html-webpack-plugin

使用yarn

yarn add --dev html-webpack-plugin

2.基本用法

該插件將為你生成一個 HTML5 文件, 其中包括使用 script 標簽的 body 中的所有 webpack 包。 只需添加插件到你的 webpack 配置如下:

const HtmlWebpackPlugin = require('html-webpack-plugin')
const path = require('path')

module.exports = {
  plugins: [
    new webpack.DefinePlugin({
      "VERSION": JSON.stringify("4711")
    }),
    new HtmlWebpackPlugin({
      filename: 'index.html',												 // 根據模板文件生成的html的文件名
      template: path.join(__dirname, 'src/index.html'), 
      chunksSortMode: 'manual',
      chunks: ['styles', 'runtime', 'polyfills', 'scripts', 'vendors', 'main']
    })
  ]
}

這將會產生一個包含以下內容的文件 dist/index.html

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="Pragma" content="no-cache"/>
  <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate"/>
  <meta http-equiv="Expires" content="0"/>
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <meta name="renderer" content="webkit">
  <meta name="force-rendering" content="webkit">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
  <title>test</title>
  <base href="/">
  <link rel="icon" type="image/png" href="favicon.png">
  <link href="styles.bf72314ba2e0c15c73f2.css" rel="stylesheet">
</head>
<body>
<app-root></app-root>
<div id="preloader">
  <div>
    <div class="loader loader--glisteningWindow"></div>
  </div>
</div>
<script src="runtime.fe0efdd131eb00c21b3a.js"></script>
<script src="vendors.6d9d661339fe7a583752.js"></script>
<script src="polyfills.5cb77843a9758f0097e1.js"></script>
<script src="scripts.d526d9658102820143d1.js"></script>
<script src="moment.65d799ec0675b5ff9b59.js"></script>
<script src="handsontable.c50df86ef38503e832a5.js"></script>
<script src="main.db888715d5d02500d39e.js"></script>
</body>
</html>

如果你有多個 webpack 入口點, 他們都會在生成的HTML文件中的 script 標簽內。

需要注意的是,默認angular-cli打包生成的入口文件也被配置成了index.html,所以我們需要更改angular.jaon文件中的配置。并且,由于Angular單頁面應用的入口文件為main.ts 所以!chunks配置中,main 一定一定要放在最后,否則運行會出錯,筆者因為沒有放在最后找了一晚上的bug~~

Angular10怎么配置webpack打包

改為:

Angular10怎么配置webpack打包

3.HtmlWebpackPlugin插件配置選項

您可以將配置選項的哈希值傳遞給html-webpack-plugin。允許的值如下:

名稱類型默認描述
title{String}Webpack App用于生成的HTML文檔的標題
filename{String}'index.html'將HTML寫入的文件。默認為index.html。您可以在這里指定一個子目錄(如:assets/admin.html
template{String}``webpack模板的相對或絕對路徑。默認情況下,它將使用(src/index.ejs如果存在)。請參閱文檔以了解詳細信息
templateContent{string、Function、false}false可用于代替template提供內聯模板-請閱讀“編寫自己的模板”部分
templateParameters{Boolean、Object、Function}false允許覆蓋模板中使用的參數-請參見示例
inject{Boolean、String}true`true
publicPath{String、'auto'}'auto'用于腳本和鏈接標簽的publicPath
scriptLoading{'blocking'、'defer'}'blocking'現代瀏覽器支持非阻塞javascript加載('defer'),以提高頁面啟動性能。
favicon{String}``將給定的圖標圖標路徑添加到輸出HTML
meta{Object}{}允許注入meta-tags。例如meta: {viewport: 'width=device-width, initial-scale=1, shrink-to-fit=no'}
base{Object、String、false}false注入base標簽。例如base: "https://example.com/path/page.html
minify{Boolean、Object}true如果mode'production',否則false控制是否以及以何種方式最小化輸出。有關更多詳細信息,請參見下面的縮小。
hash{Boolean}false如果是,true則將唯一的webpack編譯哈希值附加到所有包含的腳本和CSS文件中。這對于清除緩存很有用
cache{Boolean}true僅在文件被更改時發出文件
showErrors{Boolean}true錯誤詳細信息將寫入HTML頁面
chunks{?}?僅允許您添加一些塊(例如,僅單元測試塊)
chunksSortMode{String、Function}auto允許控制在將塊包含到HTML中之前應如何對其進行排序。允許值為`'none'
excludeChunks{Array.<string>}``允許您跳過一些塊(例如,不添加單元測試塊)
xhtml{Boolean}false如果truelink標簽呈現為自動關閉(符合XHTML)

最后奉上完整的webpack.partial.js

const webpack = require('webpack')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const HtmlWebpackPlugin = require('html-webpack-plugin')
const path = require('path')

module.exports = {
  externals: {        // 打包除外的文件
    echarts: 'echarts'
  },
  optimization: {
    splitChunks: {
      chunks: "all",
      minSize: 20000,
      minChunks: 1,
      maxAsyncRequests: 5,
      maxInitialRequests: 3,
      automaticNameDelimiter: '~',
      name: true,
      cacheGroups: {
        moment: {
          name: 'moment',
          test: /[\\/]node_modules[\\/]moment[\\/]/,
          priority: -6
        },
        handsontable: {
          name: 'handsontable',
          test: /[\\/]node_modules[\\/]handsontable[\\/]/,
          priority: -7
        },
        angular: {
          name: 'angular',
          test: /[\\/]node_modules[\\/]@angular[\\/]/,
          priority: -9
        },
        vendors: {
          name: 'vendors',
          test: /[\\/]node_modules[\\/]/,
          priority: -10
        },
        default: {
          name: 'default',
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true
        }
      }
    }
  },
  plugins: [
    new BundleAnalyzerPlugin({
      analyzerMode: 'static',
    }),
    new webpack.DefinePlugin({
      "VERSION": JSON.stringify("4711")
    }),
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: path.join(__dirname, 'src/index.html'),
      chunksSortMode: 'manual',
      chunks: ['styles', 'runtime', 'polyfills', 'scripts', 'vendors', 'main']      // 限定順序,main.js必須在最后
    })
  ]
}

以上是“Angular10怎么配置webpack打包”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女