この記事では、Angular10 で Webpack パッケージ化を構成する方法を紹介します。一定の参考値があるので、困っている友達が参考になれば幸いです。
Angular プロジェクトでは、angular-cli を使用してパッケージ化されたプロジェクトを作成することをお勧めします。Angular はデフォルトで構成に役立ちます。
ただし、特別なニーズがある場合には、明らかに柔軟性が高くありません。たとえば、いくつかの大きなパッケージング ファイルを分割し、各パッケージング ファイルの構成を分析し、webpack のいくつかのパラメータをカスタマイズしたい場合、次のような方法がありません。始める。
多くのプロジェクトに共通する依存関係は、日付ライブラリ moment.js
です。これにはロケールを使用する機能も含まれますが、バンドル全体のサイズが大幅に増加します。これらはすべて最適化する必要がある領域です。
推奨されるツール ライブラリは次のとおりですngx-build-plus ではなく、多くのことを変更したり、既存のプロジェクトに統合したりできます。次に使い方を説明しますが、具体的な詳細についてはgithubにあるドキュメントを参照してください。公式ドキュメントには利用可能なバージョンは 9 としか記載されていませんが、Angular 10 も使用できます。
ng add ngx-build-plus
注 : projects
フォルダー内の特定のサブプロジェクトに追加する場合は、次のようにしてください。 --project
スイッチを使用してそれを指します: ng add ngx-build-plus --project Getting-started
Remark:このステップでは、Angular >= 7 および CLI >= 7 バージョンの NPM インストール パッケージを渡します。プロジェクトでカスタム ジェネレーターを使用して、angular.jsonngserve
および ng build# # を更新します。 #。ただし、バージョン 6 ではインストールが成功しない可能性があります。この場合は、
yarn ngx-build-plus --dev を直接追加し、
angular.json 内の次の 2 つの場所を変更してください。 ファイル:
"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. ファイル を作成し、次の内容を追加します(サブ) プロジェクトのルート ディレクトリ:
const webpack = require('webpack'); module.exports = { plugins: [ new webpack.DefinePlugin({ "VERSION": JSON.stringify("4711") }) ] }
でグローバル変数 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; }
アプリケーションを開始するための Webpack 構成の一部を指すスイッチ:
ng serve --extra-webpack-config webpack.partial.js -o
-- project switch:
ng serve --project getting-started -o --extra-webpack-config webpack.partial.js
ヒント: このコマンド用の npm スクリプトの作成を検討してください。
6. Webpack 設定によって提供されるバージョンが表示されていることを確認してください。印刷結果が表示された場合は、プロジェクトで webpack.partial.js ファイルの構成が有効になったことを意味します。 .js
には必要な機能が追加されていますが、筆者は主に 2 つの主要な部分に焦点を当てました。
$ yarn add webpack-bundle-analyzer --dev
#3 の文 module.exports = webpackConfig
の上に <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
module.exports = {
plugins: [
new BundleAnalyzerPlugin({
analyzerMode: 'static',
}),
new webpack.DefinePlugin({
"VERSION": JSON.stringify("4711")
})
]
}</pre><div class="contentsignin">ログイン後にコピー</div></div>## を追加します。
webpack -p --progress または、通常の devServer サービスを開始してビューアを開始します!
4. 結果
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' // 日志级别。可以是'信息','警告','错误'或'沉默'。 }),
在 webpack4.x 中,我们使用 optimization.splitChunks 来分离公用的代码块。SplitChunks插件简单的来说就是Webpack中一个提取或分离代码的插件,主要作用是提取公共代码,防止代码被重复打包,拆分过大的js文件,合并零散的js文件。
这里说的分离,当然只是针对一些第三方库(一般来自 node_modules),以及我们自己定义的工具库(或公用方法)。
不知如何下手?首先,我们来看官网给的一份
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。它表示将哪种类型的模块分离成新文件。字符串参数值的作用分别如下:
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: 该属性值的数据类型可以为布尔值。它表示针对已经分离的模块,不再重新分离。
要将第三方库分离出来,我们需要调整配置文件,设置 chunks: 'all'
,即表示让所有加载类型的模块在某些条件下都能打包。
打包中,我们发现,工具函数模块(utils)的源码被分别打包到了两个文件中,这显然是不对。之所以出现这种情况,是因为我们设置了 minSize: 30000,即分离成独立文件的最小体积为 30K,而这里的 工具函数(utils.js)只有几KB,所以,没被分离成单独的文件。
有的时候,我们希望将所有来自 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 } } } } }
chunks
选项,决定要提取那些模块。
默认是async
:只提取异步加载的模块出来打包到一个文件中。
异步加载的模块:通过import('xxx')
或require(['xxx'],() =>{})
加载的模块。
initial
:提取同步加载和异步加载模块,如果xxx在项目中异步加载了,也同步加载了,那么xxx这个模块会被提取两次,分别打包到不同的文件中。
同步加载的模块:通过 import xxx
或require('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
时,忽略minSize
,minChunks
,maxAsyncRequests
和maxInitialRequests
外面选项
HtmlWebpackPlugin
简化了HTML文件的创建,以便为你的webpack包提供服务。这对于在文件名中包含每次会随着编译而发生变化哈希的 webpack bundle 尤其有用。 你可以让插件为你生成一个HTML文件,这个插件有两个重要作用。
npm install --save-dev html-webpack-plugin
使用yarn
yarn add --dev html-webpack-plugin
该插件将为你生成一个 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~~
改为:
您可以将配置选项的哈希值传递给html-webpack-plugin
。允许的值如下:
タイプ | デフォルト | 説明 | |
---|---|---|---|
##title ##{文字列} |
Webpack アプリ |
タイトル生成された HTML ドキュメントに使用する |
|
{String} |
'index.html' |
HTML を書き込むファイル。デフォルトは index.html | です。ここでサブディレクトリを指定できます (例: assets/admin.html)
|
{String} |
`` |
webpack | テンプレートへの相対パスまたは絶対パス。デフォルトでは、(src/index.ejs (存在する場合)) が使用されます。詳細については、 Documentation を参照してください。
|
##{string, Function, false} |
false を | templateの代わりに使用して、インライン テンプレートを提供できます。「 | 独自のテンプレートの作成」 セクションをお読みください。
| #templateParameters
##{ブール値、オブジェクト、関数} | false
テンプレートで使用されるパラメーターをオーバーライドできるようにします - | Example
|
inject | # を参照してください。
##{ブール値、文字列} true |
`true |
| publicPath|
{String,'auto'} 'auto' |
スクリプトとリンク タグの publicPath |
#scriptLoading |
|
##'blocking' | 最新のブラウザでは、ページの起動を改善するためにノンブロッキング JavaScript の読み込み ('defer') がサポートされています。パフォーマンス。
|
#ファビコン |
##{文字列} |
指定されたアイコン アイコン パスを出力 HTML
|
meta |
{ オブジェクト} に追加します。 | |
{} meta | タグの挿入を許可します。例: meta: {viewport: 'width=device-width、initial-scale=1、shrink-to-fit=no'}
|
| base
{オブジェクト、文字列、false}
|
インジェクション ベース |
タグ。たとえば、base: "https://example.com/path/page.html
|
| ##minify
{ブール値、オブジェクト}
|
mode が 'production' の場合、それ以外の場合false |
出力を最小化するかどうか、およびその方法を制御します。詳細については、以下の Minify | を参照してください。
ハッシュ
| ##{ブール値}false |
はいの場合、true含まれるすべてのスクリプトと CSS ファイルに一意の webpack コンパイル ハッシュを追加します。これはキャッシュをクリアするのに役立ちます |
|
cache
|
{ブール値}
| true
ファイルを出力
|
showErrors
|
{Boolean} ## ファイルが変更された場合のみ |
#true |
| chunks |
{?}
| #?##一部のブロックのみ (たとえば、単体テスト ブロックのみ) を追加できます |
chunksSortMode |
##{String, Function} |
auto |
次の制御を許可しますHTML に含める前にブロックをどのように並べ替える必要があるか。許可される値は「none」です |
excludeChunks | {Array.<string>}</string> |
`` を使用すると、一部のチャンクをスキップできます (単体テスト ブロックを追加せずになど) | |
xhtml
| {ブール値} | falseIf | true|
タグを自動終了タグとしてレンダリングします (XHTML 準拠) 最后奉上完整的 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 パッケージを構成するにはどうすればよいですか?手法の紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。