Angular 17中如何通过'main'字符串获取Assets文件夹内文件路径
解决动态加载带Hash的子项目脚本文件问题
方法一:利用Webpack Manifest插件生成映射文件
在子项目的Webpack配置中添加Manifest插件,打包时自动生成包含文件名映射的manifest.json,前端通过读取这个文件获取最新的脚本路径:
- 安装插件:
npm install webpack-manifest-plugin --save-dev
- 修改子项目
webpack.config.js:
const ManifestPlugin = require('webpack-manifest-plugin'); module.exports = { // 其他原有配置 plugins: [ new ManifestPlugin({ fileName: 'manifest.json', basePath: 'assets/projects/observability/' // 对应主项目中的路径前缀 }) ] };
- 前端组件中动态加载脚本:
import { HttpClient } from '@angular/common/http'; import { Renderer2 } from '@angular/core'; // 组件构造函数注入依赖 constructor(private http: HttpClient, private renderer: Renderer2) {} loadSubProjectScripts() { this.http.get('assets/projects/observability/manifest.json').subscribe((manifest: any) => { // 从manifest中获取main对应的打包后文件名 const mainScriptPath = `assets/projects/observability/${manifest['main.js']}`; // 创建并插入脚本标签 const script = this.renderer.createElement('script'); script.src = mainScriptPath; this.renderer.appendChild(document.head, script); }); }
方法二:构建脚本自动生成配置文件
如果不用Webpack插件,可以在子项目打包完成后,用Node脚本提取main-*.js的文件名,写入配置文件供前端读取:
- 子项目
package.json添加打包后脚本:
{ "scripts": { "build": "your-build-command && node ./generate-config.js" } }
- 创建
generate-config.js脚本:
const fs = require('fs'); const path = require('path'); // 子项目dist目录路径 const distDir = path.resolve(__dirname, 'dist'); // 匹配以main-开头、.js结尾的文件 const mainScript = fs.readdirSync(distDir).find(file => /^main-.+\.js$/.test(file)); // 写入配置文件到dist目录 fs.writeFileSync( path.join(distDir, 'script-config.json'), JSON.stringify({ mainScript }) );
- 前端组件中加载脚本:
import { HttpClient } from '@angular/common/http'; import { Renderer2 } from '@angular/core'; constructor(private http: HttpClient, private renderer: Renderer2) {} loadSubProjectScripts() { this.http.get('assets/projects/observability/script-config.json').subscribe((config: any) => { const mainScriptPath = `assets/projects/observability/${config.mainScript}`; const script = this.renderer.createElement('script'); script.src = mainScriptPath; this.renderer.appendChild(document.head, script); }); }
方法三:服务器端配合返回目录文件列表(需服务器支持)
如果你的服务器允许访问目录列表,可以直接请求对应目录,筛选出目标脚本文件:
import { HttpClient } from '@angular/common/http'; import { Renderer2 } from '@angular/core'; constructor(private http: HttpClient, private renderer: Renderer2) {} loadSubProjectScripts() { // 注意:需服务器配置允许返回assets/projects/observability目录的文件列表 this.http.get('assets/projects/observability/', { responseType: 'text' }).subscribe(dirHtml => { // 正则匹配html中的main-*.js文件名 const match = dirHtml.match(/main-.+\.js/); if (match) { const mainScriptPath = `assets/projects/observability/${match[0]}`; const script = this.renderer.createElement('script'); script.src = mainScriptPath; this.renderer.appendChild(document.head, script); } }); }
内容的提问来源于stack exchange,提问作者jitesh vijay
相关产品推荐
相关产品推荐

