ng build 和 ng build --watch 之间的捆绑输出不一致

3
当运行常规的ng buildng build --watch时,为什么Angular会生成不同的打包文件呢?
我通过在使用ng new创建的应用程序上运行ng buildng build --watch进行验证。
我需要事先知道这些打包文件的名称,因为它们将与ASP.NET的BundleConfig一起使用,所以我希望生成的输出在常规构建和带有观察标志的构建之间保持一致。
我正在使用Angular 8。
如您下面所见,ng build --watch生成的构建输出不会将es5/es2015附加到打包文件名称中,除了polyfills。
$ ng build

Date: 2019-06-05T06:48:01.672Z
Hash: 36c34ee221d2ae159bb9
Time: 6625ms
chunk {main} main-es5.js, main-es5.js.map (main) 10.4 kB [initial] [rendered]
chunk {polyfills} polyfills-es5.js, polyfills-es5.js.map (polyfills) 546 kB [initial] [rendered]
chunk {runtime} runtime-es5.js, runtime-es5.js.map (runtime) 6.08 kB [entry] [rendered]
chunk {styles} styles-es5.js, styles-es5.js.map (styles) 16.7 kB [initial] [rendered]
chunk {vendor} vendor-es5.js, vendor-es5.js.map (vendor) 3.7 MB [initial] [rendered]

Date: 2019-06-05T06:48:06.348Z
Hash: efd3de5e2da11726f422
Time: 4639ms
chunk {main} main-es2015.js, main-es2015.js.map (main) 10.1 kB [initial] [rendered]
chunk {polyfills} polyfills-es2015.js, polyfills-es2015.js.map (polyfills) 250 kB [initial] [rendered]
chunk {runtime} runtime-es2015.js, runtime-es2015.js.map (runtime) 6.08 kB [entry] [rendered]
chunk {styles} styles-es2015.js, styles-es2015.js.map (styles) 16.7 kB [initial] [rendered]
chunk {vendor} vendor-es2015.js, vendor-es2015.js.map (vendor) 3.61 MB [initial] [rendered]

$ ng build --watch

Date: 2019-06-05T06:48:44.350Z
Hash: 55cc7c8d13a9047850cc
Time: 7073ms
chunk {main} main.js, main.js.map (main) 10.1 kB [initial] [rendered]
chunk {polyfills} polyfills.js, polyfills.js.map (polyfills) 248 kB [initial] [rendered]
chunk {polyfills-es5} polyfills-es5.js, polyfills-es5.js.map (polyfills-es5) 380 kB [initial] [rendered]
chunk {runtime} runtime.js, runtime.js.map (runtime) 6.08 kB [entry] [rendered]
chunk {styles} styles.js, styles.js.map (styles) 16.7 kB [initial] [rendered]
chunk {vendor} vendor.js, vendor.js.map (vendor) 3.61 MB [initial] [rendered]

只需使用“build”命令的名称,因为您不会在生产模式下观看构建过程。我真的没有看到问题在哪里... - user4676340
问题出现在开发中,我们想使用 --watch 标志,因为它比常规构建快得多。不幸的是,在开发中我们不能使用 ng serve 命令,因为应用程序的某些部分是由 ASP.NET Razor 服务器呈现的。主要目标是能够使用 ng serve,但我们还没有达到这个目标。 - langen
那么,专注于你的主要目标,而不是浪费时间在那上面!我会发布一篇可能会帮助你的答案。 - user4676340
3个回答

4

我在StackOverflow上发布了一个类似的问题。我注意到当运行ng buildng build --watch时,bundle是不同的。如果你想知道它们为什么不同... 由ng build输出的bundles的ES5版本支持新的Angular 8差分加载功能。结果发现默认情况下ng serveng build --watch禁用了差分加载功能以提高性能。这个Github讨论提供了一个很好的解释,以及在这些场景中需要使用差分加载的解决方法。


谢谢。这正是我在寻找的答案 :) - langen

1

针对不同的目的,我遇到了同样的问题:一旦构建完成,我必须编写一个ASP.NET文件来总结捆绑包,以便可以在index.cshtml文件中手动编写。

我只需运行一个小的节点脚本,在每次构建后使用--stats-json标志即可。这是它:

const fs = require('fs');

// Don't do if dist not existing
if (!fs.existsSync('./dist')) return;
if (!fs.existsSync('./dist/myProject/stats.json')) return;

// Remove previous file
if (fs.existsSync('./dist/myProject/bundle-chunks.json')) fs.unlinkSync('./dist/myProject/bundle-chunks.json');

// Read file, parse to JSON
const statsStr = fs.readFileSync('./dist/myProject/stats.json').toString();
const statsJson = JSON.parse(statsStr);

// Get corresponding property
const assets = statsJson.assetsByChunkName;

// Transform the object into an array with more information
const payload = Object.keys(assets).reduce((pk, nk) => {
  const key = nk;
  const ext = assets[nk].split('.').pop();
  const path = assets[nk];
  pk.push({ key, ext, path });
  return pk;
}, []);

// Reduce the array to build a JSON object of typ { scripts: [], styles: [] }
const metas = payload.reduce((p, n) => {
  if (n.ext === 'js')
    p.scripts.push(`<script type="text/javascript" src="./${n.path}" ${n.path.includes('polyfill') ? 'nomodule' : ''}></script>`);
  if (n.ext === 'css')
    p.styles.push(`<link rel="stylesheet" href="./${n.path}">`);
  return p;
}, { styles: [], scripts: [] });

// Save in file
fs.writeFileSync('./dist/myProject/bundle-chunks.json', JSON.stringify(metas, null, 2));

// Notify
console.log('Bundle chunks written to bundle-chunks.json file');

// Scripts files are to be added to the end of the body (to incread load time and let the page display itself while loading)
// Style files are to be added to the head of the application.

0

我通过在非开发环境中仅使用BundleConfig解决了这个问题。因为bundle的名称带有哈希值,所以我只需要在非开发环境中使用BundleConfig。

在开发时,我必须使用ng build --watch而不是ng build。

这不是最好的解决方案,但在重构应用程序以便我们可以使用ng serve之前,这对我来说是可行的。

    @if (Model.IsDev)
    {
        @{ /* These are produced when running ng build --watch }
        <script src="/Static/dist/runtime.js"></script>
        <script src="/Static/dist/polyfills-es5.js" nomodule></script>
        <script src="/Static/dist/polyfills.js"></script>
        <script src="/Static/dist/scripts.js"></script>
        <script src="/Static/dist/vendor.js"></script>
        <script src="/Static/dist/main.js"></script>
    }
    else
    {
        @{ /* These are produced when running ng build or ng build --prod }
        @Scripts.RenderFormat("<script src='{0}' type='module'></script>", "~/scripts/runtime-es2015")
        @Scripts.RenderFormat("<script src='{0}' type='module'></script>", "~/scripts/polyfills-es2015")
        @Scripts.RenderFormat("<script src='{0}' nomodule></script>", "~/scripts/runtime-es5")
        @Scripts.RenderFormat("<script src='{0}' nomodule></script>", "~/scripts/polyfills-es5")
        @Scripts.Render("scripts")
        @Scripts.RenderFormat("<script src='{0}' type='module'></script>", "~/scripts/vendor-es2015")
        @Scripts.RenderFormat("<script src='{0}' type='module'></script>", "~/scripts/main-es2015")
        @Scripts.RenderFormat("<script src='{0}' nomodule></script>", "~/scripts/vendor-es5")
        @Scripts.RenderFormat("<script src='{0}' nomodule></script>", "~/scripts/main-es5")
    }

我的 BundleConfig 看起来是这样的:

    public class BundleConfig
    {
        public static void RegisterBundles(BundleCollection bundles, bool isDevEnv)
        {
            // Already minified by angular-cli
            BundleTable.EnableOptimizations = false;

            if (!isDevEnv)
            {
                bundles.Add(new StyleBundle("~/styles")
                    .Include("~/Static/dist/styles.*"));

                bundles.Add(CreateScriptBundle("runtime-es2015"));
                bundles.Add(CreateScriptBundle("polyfills-es2015"));
                bundles.Add(CreateScriptBundle("runtime-es5"));
                bundles.Add(CreateScriptBundle("polyfills-es5"));
                bundles.Add(CreateScriptBundle("scripts"));
                bundles.Add(CreateScriptBundle("vendor-es2015"));
                bundles.Add(CreateScriptBundle("main-es2015"));
                bundles.Add(CreateScriptBundle("vendor-es5"));
                bundles.Add(CreateScriptBundle("main-es5"));  
            }
        }

        private static Bundle CreateScriptBundle(string name)
        {
            return new ScriptBundle($"~/scripts/{name}")
                .Include($"~/Static/dist/{name}.*");
        }
    }

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