Assets revisioning using angular custom builder

丶灬走出姿态 提交于 2020-06-17 13:27:26

问题


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)

  1. Load TypeScript files (using awesome-typescript-loader)
  2. Load templateUrl and styleUrls from Angular components (using angular2-template-loader)
  3. Load HTML files
  4. 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:


  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.

  2. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!