Angular构建过程中,何时生成index.html文件?

3

我正在尝试弄清楚Angular在构建阶段生成 index.html 文件的时间,以便我可以在此之后将其移动到另一个目录。 我注意到当我尝试使用 WebpackShellPlugin 复制文件时,在 onBuildEndonBuildExit 阶段都没有将 index.html 文件复制到 dist/projectToMove 目录。

Webpack配置如下:

const WebpackShellPlugin = require('webpack-shell-plugin');

module.exports = {
  plugins: [
    new WebpackShellPlugin({
      onBuildEnd: [
        'echo "Files at end of compilation: "',
        'ls ./dist/apps/curemedit/'
      ],
      onBuildExit: [
        'echo "Copying Popup App contents..."',
        'ls ./dist/apps/curemedit/',
        'cp -rvf ./dist/apps/curemedit/* ./dist/apps/'
      ],
      safe: true
    })
  ]
};

两种情况下ls的输出结果:

favicon.ico
main.js
main.js.map
manifest.json
polyfills.js
polyfills.js.map
runtime.js
runtime.js.map
styles.js
styles.js.map
vendor.js
vendor.js.map

我有一个用于浏览器扩展的多应用Angular工作区。其中projectToMove将用于此扩展的弹出窗口显示。我试图将其对应文件夹中的内容向上移动一个级别,以便与扩展根目录中的清单文件在一起。
我猜想生成index.html文件时的延迟是由差异加载的ES5包生成引起的。我在此项目的browserslist文件中设置了Chrome >= 61,但事实证明这没有效果。
应该怎样正确地抓取index.html文件?我应该使用node脚本更长时间地观察该文件夹,还是有更优雅的解决方案?
关于我的用例的其他信息:
我正在构建一个浏览器扩展程序。之前,当它是单个项目的Angular工作区时,使用webpack-extension-reloader进行实时重新加载,如此处所述。现在,我有两个独立的Angular项目,用于弹出窗口和选项页面,这两个项目的对应index.html页面都希望在扩展根文件夹中获取js和css文件。因此,我现在使用CopyPlugin、WebpackShellPlugin和一些sed命令来实现这种丑陋的hack。
以下是添加的构建配置文件:
ext.config.js:
const CopyPlugin = require('copy-webpack-plugin');
const WebpackShellPlugin = require('webpack-shell-plugin');

module.exports = {
  entry: {
    background: './src/chrome/background.ts'
  },
  plugins: [
    new CopyPlugin([
      {
        from: './src/chrome/manifest.json',
        to: '../manifest.json'
      }
    ]),
    new WebpackShellPlugin({
      onBuildExit: [
        // Rename sourcemaps, js and css files -> undo chunks' renamings -> move them to extension root
        'echo "Moving Options App Contents..."',
        'for f in ./dist/apps/proj1/*.js.map; do mv "$f"  "${f%.js.map}.proj1.js.map"; done ',
        'for f in ./dist/apps/proj1/*.js; do mv "$f"  "${f%.js}.proj1.js"; done ',
        'mv ./dist/apps/proj1/styles.css ./dist/apps/proj1/styles.proj1.css',
        'for f in ./dist/apps/proj1/[0-9].proj1.js; do mv "$f" "${f%.proj1.js}.js"; done ',
        'for f in ./dist/apps/proj1/workspace*.proj1.js; do mv "$f" "${f%.proj1.js}.js"; done ',
        'for f in ./dist/apps/proj1/workspace*.proj1.js.map; do mv "$f" "${f%.proj1.js.map}.js.map"; done ',
        'mv -v ./dist/apps/proj1/* ./dist/apps/'
      ],
      safe: true
    })
  ]
};

ext.popup.js:

const WebpackShellPlugin = require('webpack-shell-plugin');

module.exports = {
  plugins: [
    new WebpackShellPlugin({
      onBuildExit: [
        'echo "Moving Popup App Contents..."',
        'for f in ./dist/apps/proj2/*.js.map; do mv "$f"  "${f%.js.map}.proj2.js.map"; done ',
        'for f in ./dist/apps/proj2/*.js; do mv "$f"  "${f%.js}.proj2.js"; done ',
        'mv ./dist/apps/proj2/styles.css ./dist/apps/proj2/styles.proj2.css',
        'mv -v ./dist/apps/proj2/* ./dist/apps/'
      ],
      safe: true
    })
  ]
};

sed.sh:

#!/bin/sh

sed -i 's/.js/.proj1.js/g' ./dist/apps/proj1/index.html
sed -i 's/styles.css/styles.proj1.css/g' ./dist/apps/proj1/index.html
sed -i 's/.js/.proj2.js/g' ./dist/apps/proj2/index.html
sed -i 's/styles.css/styles.proj2.css/g' ./dist/apps/proj2/index.html

package.json:

"build": "rm -rf ./dist/ && ng build proj1 && ng build proj2 && ./sed.sh",
"buildprod": "rm -rf ./dist/ && ng build proj1 --prod && ng build proj2 --prod && ./sed.sh"

我使用了一个 postbuild 的 npm 脚本来完成这个任务。所以每次运行 build 命令时,都会运行 postbuild;它只是调用一个节点脚本来移动文件。 - C.OG
这对我不起作用,因为我需要运行 ng build project1 --watch,而后构建脚本会在这种情况下给我带来错误。因此,我没有实时重新加载和调试的选择。 - Risav Karna
你的使用场景是什么?为什么需要这样做? - C.OG
@c_ogoo,我已经更新了答案。主要是因为我需要能够进行实时重新加载并测试我的扩展程序的更改,以便保持足够快的开发速度。 - Risav Karna
我需要了解构建生命周期阶段... - Risav Karna
3个回答

7

我不完全理解您的用例,但希望这能帮到您。

Angular CLI允许配置index属性。默认情况下,这仅是一个路径,指定了index.html文件在src目录中的位置。然后输出路径将与输入路径相同。但是CLI还接受一个对象,该对象指定输入路径和输出路径。

该属性深度嵌套在angular.json文件中。在新生成的应用程序中,它位于projects > project-name > architect > build > index

"index": {
    "input": "src/index.html",
    "output": "../index.html"
}

这将把index.html文件放置在其他文件的上一级。不幸的是,这不会改变index.html文件内其他文件的引用。这仍然需要在外部进行。我认为这是一个错误,因此创建了一个错误报告


感谢您的见解和错误报告。情况是我有两个index.html文件,它们都期望在根文件夹中引用其js/css文件。这些index.html文件本身默认位于它们自己的proj1和proj2子文件夹中,但由于某种原因,我不需要更改index.html文件中js/css文件路径,以指向同一文件夹而不是上一级。所以幸运的是,这个错误实际上并没有影响我的使用情况。 - Risav Karna

1
为什么不直接将构建结果输出到正确的文件夹中?如果你可以将输出放在你想要的目标文件夹中,何必去对抗构建呢?
使用 @angular/cli,我会编辑 angular.json 文件,使 "outputPath" 不是 "dist/appname",而是适合你的用例的任何路径。
无论如何,我认为 index.html 是你真正不需要复制的单个文件:它的内容从不更改,至少如果你保持文件名一致,没有哈希码。
为什么不在你需要的任何地方保留一个预编译的 index.html,并将构建输出放在子文件夹中呢?

3个原因:我有两个index.html文件,它们都期望在根目录下引用其js/css文件。它们的内容因为是来自于不同的开发或生产构建过程而略有不同。如果我将构建文件放在子文件夹中,我仍然必须修改html文件中的路径引用,因为默认情况下这些引用会被认为是在同一个目录下。 - Risav Karna

0
我所做的只是:
  • 将 firebase.json 的目标更新为正确的文件路径,即 Index.html 所在的位置。
  • 重新运行构建操作,
  • 重新运行 firebase deploy。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接