Angular构建时如何根据--prod参数动态修改index.html脚本URL
Got it, let's tackle this problem of dynamically updating the script src in your Angular app's index.html based on whether you run a regular ng build or ng build --prod. Here are a few practical approaches that work well:
方案1:使用环境变量+自定义Webpack配置(推荐)
This approach keeps your environment-specific values organized and avoids modifying source files directly.
Step 1: Add script URLs to environment files
Open your development environment file (src/environments/environment.ts) and add your dev script URL:export const environment = { production: false, scriptUrl: 'https://your-dev-domain/dev.js' // 开发环境脚本地址 };Then update the production environment file (
src/environments/environment.prod.ts):export const environment = { production: true, scriptUrl: 'https://my-site.net/prod.js' // 生产环境脚本地址 };Step 2: Install custom webpack builder
We'll use@angular-builders/custom-webpackto extend Angular's default build process:npm install @angular-builders/custom-webpack --save-devStep 3: Create a custom webpack config
Make a new filewebpack.extra.jsin your project root:const HtmlWebpackPlugin = require('html-webpack-plugin'); const env = process.env.NODE_ENV || 'development'; const environment = require(`./src/environments/environment.${env}.ts`).environment; module.exports = { plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', inject: true, scriptUrl: environment.scriptUrl }) ] };Step 4: Update angular.json to use the custom builder
Find thebuildsection under your project inangular.json, replace the default builder and add the custom config reference:"build": { "builder": "@angular-builders/custom-webpack:browser", "options": { "customWebpackConfig": { "path": "./webpack.extra.js" }, // Keep your existing build options here }, "configurations": { "production": { // Keep your existing production config here } } }Step 5: Update index.html with the placeholder
Modify your script tag insrc/index.htmlto use the placeholder from the webpack plugin:<script src="<%= htmlWebpackPlugin.options.scriptUrl %>"></script>Now running
ng buildwill use the dev URL, andng build --prodwill use the production URL.
方案2: 使用不同的index.html文件(简单直观)
If you only have two environments and want a no-fuss solution, this works great.
Step 1: Create a production-specific index.html
Duplicatesrc/index.htmlintosrc/index.prod.html, then update the script src in the new file to your production URL:<!-- src/index.prod.html --> <script src="https://my-site.net/prod.js"></script>Keep the original
src/index.htmlwith your dev script URL.Step 2: Configure file replacement in angular.json
In theproductionconfiguration underbuildinangular.json, add a file replacement rule:"configurations": { "production": { // Your existing production config goes here "fileReplacements": [ { "replace": "src/index.html", "with": "src/index.prod.html" }, // Keep the existing environment file replacement rule here ] } }Now when you run
ng build --prod, Angular will automatically swap in the production index.html file.
方案3: 使用npm脚本+文本替换(快速临时 fix)
This is a quick and dirty option if you don't want to mess with build configurations, but note it modifies your source index.html file directly.
For Linux/macOS users
Update yourpackage.jsonscripts:"scripts": { "build": "sed -i '' 's|https://my-site.net/prod.js|https://your-dev-domain/dev.js|g' src/index.html && ng build", "build:prod": "sed -i '' 's|https://your-dev-domain/dev.js|https://my-site.net/prod.js|g' src/index.html && ng build --prod" }Note: The empty
''after-iis required for macOS sed; omit it if you're on Linux.For Windows users
Use PowerShell commands in your scripts:"scripts": { "build": "(Get-Content src/index.html) -replace 'https://my-site.net/prod.js', 'https://your-dev-domain/dev.js' | Set-Content src/index.html && ng build", "build:prod": "(Get-Content src/index.html) -replace 'https://your-dev-domain/dev.js', 'https://my-site.net/prod.js' | Set-Content src/index.html && ng build --prod" }Warning: Make sure you commit your index.html before running these scripts, as they modify the actual file.
内容的提问来源于stack exchange,提问作者gayashanbc

