You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用正则表达式在HTML中动态引入Angular构建后的JS/CSS文件?

Got it, let's tackle this problem step by step—since you're using Angular as a Drupal theme, you can't rely on Angular's auto-generated index.html, so we need a way to dynamically pull in those hashed assets without manual updates every build.

First, let's clear up why your earlier regex attempts failed: browsers don't parse regex patterns directly in src/href attributes—they treat them as literal filenames, which is why you saw the regex string get passed straight through. We need either backend template logic (Drupal's Twig) or a post-build script + frontend JS to resolve those hashed filenames properly.

Option 1: Drupal Backend Template Logic (Most Stable)

Since Drupal uses Twig templates, we can leverage PHP in your theme's .theme file to scan the Angular dist directory, match the hashed filenames, and pass them to your Twig template. Here's how:

  1. Add a preprocess function to your theme's .theme file

    // your-angular-theme.theme
    function your_angular_theme_preprocess_html(&$variables) {
        // Path to your Angular dist folder inside the Drupal theme
        $dist_path = drupal_get_path('theme', 'your_angular_theme') . '/dist';
        $files = scandir($dist_path);
    
        // Fetch and format Angular CSS files
        $css_matches = preg_grep('/styles\.[a-f0-9]+\.css$/', $files);
        $variables['angular_css'] = array_map(function($file) use ($dist_path) {
            return file_create_url($dist_path . '/' . $file);
        }, $css_matches);
    
        // Fetch and format Angular JS files (maintain correct load order)
        $js_prefixes = ['runtime.', 'polyfills.', 'main.'];
        $variables['angular_js'] = [];
        foreach ($js_prefixes as $prefix) {
            $js_matches = preg_grep('/' . preg_quote($prefix) . '[a-f0-9]+\.js$/', $files);
            if (!empty($js_matches)) {
                $variables['angular_js'][] = file_create_url($dist_path . '/' . reset($js_matches));
            }
        }
    }
    
  2. Update your Twig template (e.g., html.html.twig)

    <!-- Load Angular CSS -->
    {% for css_file in angular_css %}
        <link rel="stylesheet" href="{{ css_file }}">
    {% endfor %}
    
    <!-- Load Angular JS in correct order -->
    {% for js_file in angular_js %}
        <script src="{{ js_file }}" defer></script>
    {% endfor %}
    

This approach is reliable because Drupal's backend directly scans the file system, so you don't have to worry about frontend fetch issues or load order mistakes.

Option 2: Post-Build Script + Frontend Dynamic Loading

If you prefer not to modify Drupal backend code, you can generate a manifest file during Angular's build process, then use frontend JS to fetch that manifest and load the correct assets.

  1. Create a Node.js script to generate a manifest
    Save this as generate-manifest.js in your Angular project root:

    const fs = require('fs');
    const path = require('path');
    
    const distDir = path.join(__dirname, 'dist');
    const manifest = {};
    
    // Scan dist folder for CSS/JS files (exclude service worker files)
    fs.readdirSync(distDir).forEach(file => {
        if (file.match(/\.(css|js)$/) && !file.includes('ngsw')) {
            manifest[file.split('.')[0]] = file; // Map prefix to full hashed filename
        }
    });
    
    // Write manifest to dist folder
    fs.writeFileSync(path.join(distDir, 'manifest.json'), JSON.stringify(manifest, null, 2));
    
  2. Add a post-build script to your Angular package.json

    "scripts": {
        "build": "ng build --prod",
        "postbuild": "node generate-manifest.js"
    }
    

    Now every time you run npm run build, a manifest.json file will be generated in your dist folder with all hashed asset filenames.

  3. Add dynamic loading code to your Drupal theme's HTML

    <script>
        // Path to your Angular dist folder in Drupal
        const angularDistPath = '/themes/your-angular-theme/dist/';
    
        // Fetch manifest and load assets
        fetch(`${angularDistPath}manifest.json`)
            .then(res => res.json())
            .then(manifest => {
                // Load CSS files
                Object.values(manifest).forEach(file => {
                    if (file.endsWith('.css')) {
                        const link = document.createElement('link');
                        link.rel = 'stylesheet';
                        link.href = angularDistPath + file;
                        document.head.appendChild(link);
                    }
                });
    
                // Load JS files in correct order
                const jsOrder = ['runtime', 'polyfills', 'main'];
                jsOrder.forEach(prefix => {
                    const file = manifest[prefix];
                    if (file) {
                        const script = document.createElement('script');
                        script.src = angularDistPath + file;
                        script.defer = true;
                        document.body.appendChild(script);
                    }
                });
            })
            .catch(err => console.error('Failed to load Angular assets:', err));
    </script>
    

Key Takeaway

Either approach will eliminate manual updates—Option 1 is more robust for Drupal environments since it leverages backend file system access, while Option 2 works if you want to keep changes isolated to the Angular side.

内容的提问来源于stack exchange,提问作者crash springfield

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:41:50