首頁  >  文章  >  web前端  >  Angular10如何配置webpack打包?方法介紹

Angular10如何配置webpack打包?方法介紹

青灯夜游
青灯夜游轉載
2021-04-12 10:36:222326瀏覽

這篇文章要跟大家介紹Angular10 配置 webpack 打包的方法。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有幫助。

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

Angular10如何配置webpack打包?方法介紹

#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.結果###### ###############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' // 日志级别。可以是'信息','警告','错误'或'沉默'。
    }),
######模組功能###:能夠查看到你的檔案打包壓縮後中真正的內容,找出那些模組組成最大的大小,找到錯誤的模組,優化它!最好的事情是它支援縮小捆綁!它解析它們以獲得實際大小的捆綁模組。它也顯示他們的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 属性即可。这里,笔者还把项目中使用到的momenthandsontableangular库单独分离出来了。

// 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 maxSizeminSize。

  • automaticNameDelimiter选项:打包生成的js文件名的分割符,默认为~

  • name选项:打包生成js文件的名称。

  • cacheGroups选项,核心重点,配置提取模块的方案。里面每一项代表一个提取模块的方案。下面是cacheGroups每项中特有的选项,其余选项和外面一致,若cacheGroups每项中有,就按配置的,没有就使用外面配置的。

  • test选项:用来匹配要提取的模块的资源路径或名称。值是正则或函数。

  • priority选项:方案的优先级,值越大表示提取模块时优先采用此方案。默认值为0。

  • reuseExistingChunk选项:true/false。为true时,如果当前要提取的模块,在已经在打包生成的js文件中存在,则将重用该模块,而不是把当前要提取的模块打包生成新的js文件。

  • enforce选项:true/false。为true时,忽略minSizeminChunksmaxAsyncRequestsmaxInitialRequests外面选项

四、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

nbsp;html>


  <meta>
  <meta>
  <meta>
  <meta>
  <meta>
  <meta>
  <meta>
  <meta>
  <title>test</title>
  <base>
  <link>
  <link>


<app-root></app-root>
<div>
  <div>
    <div></div>
  </div>
</div>
<script></script>
<script></script>
<script></script>
<script></script>
<script></script>
<script></script>
<script></script>

如果你有多个 webpack 入口点, 他们都会在生成的HTML文件中的 script 标签内。

需要注意的是,默认angular-cli打包生成的入口文件也被配置成了index.html,所以我们需要更改angular.jaon文件中的配置。并且,由于Angular单页面应用的入口文件为main.ts 所以!chunks配置中,main 一定一定要放在最后,否则运行会出错,笔者因为没有放在最后找了一晚上的bug~~

Angular10如何配置webpack打包?方法介紹

改为:

Angular10如何配置webpack打包?方法介紹

3.HtmlWebpackPlugin插件配置选项

您可以将配置选项的哈希值传递给html-webpack-plugin。允许的值如下:

'blocking'#{String}#meta##{ Object}允許注入meta{Object、String、false}#base標籤。例如是控制是否以及以何種方式最小化輸出。有關更多詳細信息,請參見下面的如果是,true則將唯一的true錯誤詳細資料將寫入HTML頁面chunks#僅允許您新增一些區塊(例如,僅單元測試區塊)chunksSortModeauto
名稱 類型 預設 #描述
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 ##scriptLoading ## {'blocking'、'defer'}
現代瀏覽器支援非阻塞javascript載入('defer'),以提高頁面啟動效能。 favicon
##``將給定的圖示圖示路徑新增至輸出HTML {}
-tags。例如meta: {viewport: 'width=device-width, initial-scale=1, shrink-to-fit=no'} #base #false
base: "https://example.com/path/page.html #minify #{Boolean、Object}true如果mode'production',否則false
縮小 hash {Boolean} false
webpack編譯雜湊值附加到所有包含的腳本和CSS檔案中。這對於清除快取很有用 cache {Boolean}
僅在檔案被變更時發出檔案 showErrors ##{{Boolean}
true
{?} ?
#{String、Function}
允許控制在將區塊包含到HTML中之前應如何對其進行排序。允許值為`'none' excludeChunks {Array.} ``允許您跳過一些區塊(例如,不加入單元測試區塊)
###xhtml###############{Boolean}####################################################################### ######false#########如果###true###將###link###標籤呈現為自動關閉(符合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必须在最后
    })
  ]
}

希望大家打包顺利,项目运行快快滴。

demo地址:
https://github.com/qinqing3761/webpack-build-demo

更多编程相关知识,请访问:编程入门!!

以上是Angular10如何配置webpack打包?方法介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除