问题
From this Stack Overflow question, I am trying to use a @angular-builders/custom-webpack:browser
with a custom Webpack config that uses html-loader and file-loader in order to rename asset files with their hash content as well as each reference to them in the source code.
The final purpose is to be able to cache the assets on in the browser but to guarantee that the user will always have the latest version of the asset (because if it changes due to a new release, the name of the asset will change too).
I started from the Angular Tour of Heroes guide (https://angular.io/tutorial) and did the following steps:
(in dashboard.component.html I added)
...
<img src="assets/angular-logo.png" />
...
I then added src/assets/angular-logo.png
I changed the angular.json
file to use a custom builder
"architect": {
"build": {
"builder": "@angular-builders/custom-webpack:browser", <------------- (changed this)
"options": {
"outputPath": "dist",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.css"
],
"scripts": []
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"customWebpackConfig": { <---------------------------------------- (added this)
"path": "custom-webpack.config.js"
},
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb",
"maximumError": "10kb"
}
]
}
}
},
...
}
Then I created custom-webpack.config.js
at the root of the application:
module.exports = {
module: {
rules: [
{
test: /\.ts$/,
loaders: ['awesome-typescript-loader', 'angular2-template-loader'],
exclude: [/\.(spec|e2e)\.ts$/]
},
{
test: /\.html$/,
use: ['html-loader']
},
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
loader: 'file-loader',
options: {
outputPath: 'assets/',
name: '[name].[contenthash].[ext]',
},
}
]
}
}
and i npm installed all the required loaders as well as @angular-builders/custom-webpack
.
From what I understand, when I run ng build --prod
, this will (on top of the existing Angular Webpack config)
- Load TypeScript files (using
awesome-typescript-loader
) - Load templateUrl and styleUrls from Angular components (using
angular2-template-loader
) - Load HTML files
- Load image files and rename them as assets with their content hash
The problem is that when I run ng build --prod
it does not seem to work as the asset image name is still angular-logo.png in dist/assets.
I feel like there is something I don't understand about the way Webpack works. What I am missing?
回答1:
You need to delete assets property in angular.json and like jonrsharpe said bring them via loaders in
import
statement. Now you need the right loaders to be activated on them.Angular puts its own loaders on your .component.css/.component.html/component.ts files, so when your webpack.config.js does not export a function - you automatically delete angular loaders
You need to apply angular loaders (ngtools/webpack/src/index.js) on your src files:
custom-webpack.config.js:
module.exports = function (angularConfig) { let rules = angularConfig.module.rules || []; // feel free to take some rules off, or change the path that they apply on // Picking up only Angular core rules from Angular default webpack config. angularConfig.module.rules = [ ...rules.filter(rule => rule.test.source.match(/@angular|\.js/)), ...rules.filter(rule => rule.test.source.match(/\.(css|scss|less|styl)/)).map(rule =>
util.replaceRawLoader(util.excludeUnnecessarryPaths(rule))), ...rules.filter(rule => rule.test.source.match(/.tsx\?/)).map(rule => util.excludeUnnecessarryPaths(rule)) ];
return merge(angularConfig, { ... your webpack configuration .... }); }
For convenience, I purpose to put a breakpoint and debug this code.
来源:https://stackoverflow.com/questions/61609178/assets-revisioning-using-angular-custom-builder