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

Angular 13项目用Webpack 5打包遇阻,求解决方案

Angular 13 + Webpack 5 打包问题解决方案

核心问题说明

升级Angular 6到Angular 13(搭配Webpack 5)时,出现错误:可注入对象'PlatformLocation'需通过JIT编译器编译,但'@angular/compiler'不可用。这是因为Angular 13默认启用AOT编译,若代码中存在触发JIT编译的场景(如动态创建组件、未正确配置AOT的依赖),但编译器未被正确引入或打包时就会触发该错误。


1. Webpack配置中异步加载Loader的实现方式

Webpack支持通过异步引入的方式加载loader,以下是两种适配方案:

方式一:ES Modules动态import()

修改webpack.config.js中的loader配置,以@ngtools/webpack为例:

{
  test: /\.[jt]sx?$/,
  exclude: /node_modules/,
  use: [
    async () => (await import('babel-loader')).default,
    async () => {
      const ngTools = await import('@ngtools/webpack');
      return {
        loader: ngTools.AngularWebpackPlugin.loader,
        options: {
          directTemplateLoading: false
        }
      };
    },
    async () => (await import('@angular-devkit/build-optimizer/webpack-loader')).default
  ]
}

方式二:CommonJS动态加载(兼容现有配置)

如果保持webpack.config.js为CommonJS格式,可使用回调式动态加载:

{
  test: /\.[jt]sx?$/,
  exclude: /node_modules/,
  use: [
    (loaderContext, callback) => {
      require.ensure([], (require) => {
        callback(null, require('babel-loader'));
      });
    },
    (loaderContext, callback) => {
      require.ensure([], (require) => {
        const ngTools = require('@ngtools/webpack');
        callback(null, {
          loader: ngTools.AngularWebpackPlugin.loader,
          options: { directTemplateLoading: false }
        });
      });
    }
  ]
}

2. Babel LinkerPlugin适配ES Modules与Node.js 14.20的解决方案

Node.js 14.20对ES Modules的支持存在部分限制,搭配Babel LinkerPlugin时需注意以下几点:

步骤1:配置Babel模块转换

安装@babel/plugin-transform-modules-commonjs,并在Babel配置中添加:

{
  "plugins": ["@babel/plugin-transform-modules-commonjs"]
}

步骤2:ES Modules格式webpack配置(改为.mjs后缀)

将webpack.config.js重命名为webpack.config.mjs,正确引入LinkerPlugin:

import { LinkerPlugin } from '@angular/compiler-cli/linker/babel';

export default async () => {
  const config = {
    // ... 现有配置
    module: {
      rules: [
        {
          test: /\.m?js$/,
          exclude: /node_modules/,
          use: {
            loader: 'babel-loader',
            options: {
              presets: ['@babel/preset-env'],
              plugins: [LinkerPlugin]
            }
          }
        }
      ]
    }
  };
  // ... 环境判断逻辑
  return config;
};

步骤3:Node.js运行兼容配置

在package.json的scripts中添加ES Modules兼容参数:

"start": "node --experimental-specifier-resolution=node webpack-dev-server --open --config webpack.config.mjs --progress --port 8080"

3. PlatformLocation错误补充修复

针对核心报错,还需调整以下配置:

  • 在webpack entry中显式引入@angular/compiler:
    entry: {
      'polyfills': './src/polyfills.ts',
      'app': './src/main.ts',
      'compiler': '@angular/compiler'
    }
    
  • 修改tsconfig.json的module配置为esnext,提升ES Modules兼容性:
    "compilerOptions": {
      "module": "esnext",
      // ... 其他配置
    }
    

相关配置文件

package.json

{"name":"my-webpack-project","version":"1.0.0","scripts":{"path":"webpack-dev-server --version","path2":"webpack --version","ng":"ng","start":"webpack-dev-server --open --config webpack.config.js --progress --port 8080","build":"webpack --mode=production --node-env=production","watch":"webpack --watch","test":"ng test","build:dev":"webpack --mode=development","build:prod":"webpack --mode=production --node-env=production","serve":"webpack serve"},"private":true,"dependencies":{"@angular-devkit/build-optimizer":"^0.1302.1","@angular/animations":"~13.4.0","@angular/common":"~13.4.0","@angular/compiler":"~13.4.0","@angular/core":"~13.4.0","@angular/forms":"~13.4.0","@angular/platform-browser":"~13.4.0","@angular/platform-browser-dynamic":"~13.4.0","@angular/router":"~13.4.0","@ngtools/webpack":"^13.3.11","@types/ws":"8.5.4","html-loader":"^4.2.0","rxjs":"~7.5.0","tsimportlib":"^0.0.5","tslib":"^2.3.0","zone.js":"~0.11.4"},"devDependencies":{"@angular-devkit/build-angular":"~13.3.11","@angular/cli":"~13.3.11","@angular/compiler-cli":"~13.4.0","@babel/core":"^7.22.9","@babel/preset-env":"^7.22.9","@types/jasmine":"~3.10.0","@types/node":"^12.11.1","@webpack-cli/generators":"^3.0.7","babel-loader":"^9.1.3","css-loader":"^6.8.1","html-webpack-plugin":"^5.5.3","jasmine-core":"~4.0.0","karma":"~6.3.0","karma-chrome-launcher":"~3.1.0","karma-coverage":"~2.1.0","karma-jasmine":"~4.0.0","karma-jasmine-html-reporter":"~1.7.0","prettier":"^3.0.0","sass":"^1.63.6","sass-loader":"^13.3.2","style-loader":"^2.0.0","ts-loader":"^9.4.4","typescript":"4.4.4","webpack":"5.76.1","webpack-cli":"^5.1.4","webpack-dev-server":"^4.15.1"},"description":"My webpack project"}

tsconfig.json

{"compileOnSave":false,"compilationMode":"partial","compilerOptions":{"resolveJsonModule":false,"baseUrl":"./","outDir":"./dist/out-tsc","importHelpers":true,"sourceMap":true,"allowSyntheticDefaultImports":true,"noImplicitAny":true,"module":"es6","target":"es5","allowJs":true,"moduleResolution":"node","experimentalDecorators":true,"lib":["es2018","dom"]},"files":["src/main.ts","src/polyfills.ts"]}

webpack.config.js

// Generated using webpack-cli https://github.com/webpack/webpack-cli

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ngToolsWebpack = require('@ngtools/webpack');
const dynamicImport = require('tsimportlib');


  const isProduction = process.env.NODE_ENV == 'production';


  const config = {
    entry: {
      'polyfills': './src/polyfills.ts',
      'app': './src/main.ts',
    },
    output: {
      path: path.resolve(__dirname, 'dist'),
      filename: "[name].js"
    },
    devtool: "source-map",
    devServer: {
      open: true,
      host: 'localhost',
      historyApiFallback: true
    },
    plugins: [
      new ngToolsWebpack.AngularWebpackPlugin({
        tsConfigPath: './tsconfig.json'

        //  entryModule: helpers.root('src/app/app.module#AppModule'),
        //  sourceMap: false,
      }),

      new HtmlWebpackPlugin({
        template: './src/index.html',
        inject: 'body'
      }),

      // Add your plugins here
      // Learn more about plugins from https://webpack.js.org/configuration/plugins/
    ],
    module: {
      rules: [
        {
          test: /\.html$/,
          use: 'html-loader'
        },
        {
          test: /\.css$/i,
          use: ['style-loader', 'css-loader'],
        },
        {
          test: /\.s[ac]ss$/i,
          use: ['style-loader', 'css-loader', 'sass-loader'],
        },
        {
          test: /\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i,
          type: 'asset',
        },
        {
          // Regular rule for all non-library files
          test: /\.[jt]sx?$/,
          exclude: /node_modules/,
          use: [
            {loader: 'babel-loader'}, // Optional
            {
              loader: '@ngtools/webpack', // Required
              options: {
                directTemplateLoading: false, // See https://www.npmjs.com/package/@ngtools/webpack
              }
            },
            {loader: '@angular-devkit/build-optimizer/webpack-loader'}, // Optional
          ]
        },

        // Add your rules for custom modules here
        // Learn more about loaders from https://webpack.js.org/loaders/
      ],
    },
    resolve: {
      extensions: ['.tsx', '.ts', '.jsx', '.js', '...'],
    },
  };

  module.exports = () => {

    if (isProduction) {
      config.mode = 'production';


    } else {
      config.mode = 'development';
    }
    return config;
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 14:17:35