如何使用Angular 7配置Webpack 4:完整指南

宰父淳
2023-12-01

by Samuel Teboul

通过塞缪尔·特布尔

如何使用Angular 7配置Webpack 4:完整指南 (How to configure Webpack 4 with Angular 7: a complete guide)

The Angular CLI makes it easy to create an application that already works, right out of the box. It is a great tool, but have you never thought: "How does it work? How can I build an application without the CLI?"

Angular CLI使开箱即用就可以轻松创建已经可以运行的应用程序。 它是一个很棒的工具,但您从未想过: “它如何工作?如何在不使用CLI的情况下构建应用程序?”

Those questions came to my mind when Angular 7 was released. I started to look for answers on the web and what I found was not up-to-date for my purpose. Indeed, as Angular and webpack are always evolving, so dependencies and configurations.

当Angular 7发布时,这些问题浮现在我的脑海。 我开始在网上寻找答案,但发现并不是最新的目的。 确实,由于Angular和webpack一直在发展,因此依赖性和配置也是如此。

In this article you are about to learn:

在本文中,您将学习:

  • How to setup an Angular 7 basic application, from scratch

    如何从头开始设置Angular 7基本应用程序
  • How to configure webpack for development mode (Just-in-Time compilation)

    如何为开发模式配置Webpack(即时编译)
  • How to configure webpack for production mode (Ahead-of-Time compilation)

    如何将Webpack配置为生产模式(提前编译)

Angular 7:设置基本应用 (Angular 7: setup a basic app)

Create a new package.json file and add the following lines to install Angular and its dependencies.

创建一个新的package.json文件,并添加以下行以安装Angular及其依赖项。

"dependencies": 
  "@angular/animations": "~7.0",
  "@angular/common": "~7.0",
  "@angular/compiler": "~7.0",
  "@angular/compiler-cli": "~7.0",
  "@angular/core": "~7.0",
  "@angular/forms": "~7.0",
  "@angular/http": "~7.0",
  "@angular/platform-browser": "~7.0",
  "@angular/platform-browser-dynamic": "~7.0",
  "@angular/platform-server": "~7.0",
  "@angular/router": "~7.0",
  "@angular/upgrade": "~7.0",
  "core-js": "~2.5",
  "rxjs": "~6.3",
  "zone.js": "~0.8"
}

I have struggled for a long time to find the best folder structure that fits every Angular project, especially when the application grows in size. This article has taught me a lot on the subject.

我一直在努力寻找适合每个Angular项目的最佳文件夹结构,尤其是在应用程序规模增大时。 这篇文章教会了我很多关于该主题的知识。

Create a new src folder and the following folders/files inside it. All our Angular app business logic will be in this folder.

创建一个新的src文件夹,并在其中创建以下文件夹/文件。 我们所有的Angular应用业务逻辑都将在此文件夹中。

src
|__ app
    |__ modules
        |__ menu
            |__ components
                |__ menu
                    |__ menu.component.html
                    |__ menu.component.scss
                    |__ menu.component.ts
            |__ menu.module.ts
            |__ menu-routing.module.ts
|__ shared
         |__ components
             |__ home
                 |__ home.component.html
                 |__ home.component.scss
                 |__ home.component.ts
|__ app.component.html
        |__ app.component.scss        
        |__ app.component.ts
        |__ app.module.ts
        |__ app-routing.module.ts
|__ index.html
|__ main.ts

Every application has at least one Angular module, the root module that you bootstrap to launch the application. By convention, it is usually called AppModule. I create another module, the MenuModule to show you how you can use lazy loading in your project, especially for production.

每个应用程序都有至少一个Angular模块,即您引导启动该应用程序的模块。 按照惯例,它通常称为AppModule 。 我创建了另一个模块MenuModule ,向您展示如何在项目中使用延迟加载,尤其是在生产中。

Some important points :

一些要点:

  • index.html

    index.html

Add <base href=”/”> tells our Angular router how to compose navigation URLs . This line means that your app will start from root folder i.e locally it would consider localhost:3000/ and on server it would consider root folder.

添加<base href=”/”>告诉我们的Angular路由器如何组成导航URL。 这行意味着您的应用将从根文件夹开始,即在本地它将考虑localhost:3000/而在服务器上将考虑根文件夹。

  • app-routing.module.ts

    app-routing.module.ts

There are three main steps to setting up a lazy loaded feature module:

设置延迟加载的功能模块的主要步骤分为三个步骤:

  1. Create the feature module

    创建功能模块
  2. Create the feature module’s routing module

    创建功能模块的路由模块
  3. Configure the routes

    配置路由

{path: ‘menu’, loadChildren:’./modules/menu/menu.module#MenuModule’} tells Angular to lazy load our feature module MenuModule by the time the user visit the /menu route.

{path: 'menu', loadChildren:'./modules/menu/menu.module#MenuModule'}告诉Angular在用户访问/menu路线时延迟加载我们的功能模块MenuModule

TypeScript配置 (TypeScript configuration)

Add the following lines to your package.json file:

package.json添加到package.json文件:

"devDependencies": {
  "@types/core-js": "~2.5",
  "@types/node": "~10.12",
  "typescript": "~3.1"
}

Create in your root project folder a tsconfig.json file:

在您的根项目文件夹中创建一个tsconfig.json文件:

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "noImplicitAny": true,
    "suppressImplicitAnyIndexErrors": true,
    "lib": ["es6", "dom"],
    "typeRoots": ["node_modules/@types"]
  },
  "exclude": ["node_modules"]
}

This is a basic TypeScript configuration file. It’s essential to install node and core-js types definition. Without it, TypeScript won’t be able to compile our Angular application to JavaScript.

这是基本的TypeScript配置文件。 必须安装nodecore-js类型定义。 没有它,TypeScript将无法将Angular应用程序编译为JavaScript。

用于开发模式的Webpack配置(及时编译) (Webpack configuration for development mode (Just-in-Time compilation))

First of all, what does compilation means ? It doesn’t mean compiling TypeScript files to JavaScript, this is not related to Angular. Angular itself needs to compile your HTML templates into JavaScript and this can occurred at 2 different points of time:

首先, 编译意味着什么? 这并不意味着将TypeScript文件编译为JavaScript,这与Angular无关。 Angular本身需要将HTML模板编译为JavaScript,这可能会在2个不同的时间点发生:

  • After your app is downloaded in the Browser (JiT)

    在浏览器(JiT)中下载应用程序后
  • Right after development, at build time, before your app is downloaded in the Browser (AoT)

    在开发之后,即在构建时,在将应用程序下载到浏览器(AoT)中之前

什么是webpack? (What is webpack?)

According to Wikipedia:

根据维基百科:

Webpack is an open source JavaScript module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset. Webpack takes modules with dependencies and generates static assets representing those modules. It’s a module bundler primarily for JavaScript, but it can transform front-end assets like HTML, CSS, even images if the corresponding plugins are included.
Webpack是一个开源JavaScript模块捆绑程序。 它的主要目的是捆绑JavaScript文件以供在浏览器中使用,但它也能够转换,捆绑或打包几乎任何资源或资产。 Webpack接收具有依赖性的模块,并生成代表这些模块的静态资产。 这是一个主要用于JavaScript的模块捆绑器,但如果包括相应的插件,它也可以转换HTML,CSS甚至图像之类的前端资产。

To tell webpack how to bundle our application we have to configure what we call the Core Concepts:

为了告诉webpack如何捆绑我们的应用程序,我们必须配置我们所谓的核心概念

Entry — An entry point indicates which module webpack should use to begin building out its internal dependency graph. Webpack will figure out which other modules and libraries that entry point depends on (directly and indirectly).

入口—入口点指示webpack应该使用哪个模块开始构建其内部依赖关系图 。 Webpack将找出入口点所依赖的其他模块和库(直接和间接)。

Output — The output property tells webpack where to emit the bundles it creates and how to name these files. It defaults to ./dist/main.js for the main output file and to the ./dist folder for any other generated file.

输出-输出属性告诉webpack在哪里发出它创建的包以及如何命名这些文件。 缺省为./dist/main.js主输出文件,以及到./dist任何其他生成的文件夹中。

Loaders — At a high level, loaders have two properties in your webpack configuration:

加载程序-总体而言,加载程序在Webpack配置中具有两个属性:

  • The test property identifies which file or files should be transformed.

    测试属性标识应转换的文件。
  • The use property indicates which loader should be used to do the transforming.

    use属性指示应使用哪个加载程序进行转换。

Plugins — While loaders are used to transform certain types of modules, plugins can be leveraged to perform a wider range of tasks like bundle optimization, asset management, and injection of environment variables.

插件-使用加载程序来转换某些类型的模块时,可以利用插件来执行更广泛的任务,例如包优化,资产管理和环境变量的注入。

All of these must be set up in the webpack configuration file webpack.config.js.

所有这些都必须在webpack配置文件webpack.config.js.进行设置webpack.config.js.

配置Webpack (Configuring webpack)

In the src folder we need to create 2 more files:

src文件夹中,我们需要再创建2个文件:

  • vendor.ts that only imports the application's third-party modules.

    仅导入应用程序的第三方模块的vendor.ts

  • polyfills.ts we need polyfills to run an Angular application in most browsers as explained in the Browser Support guide. This bundle file will load first so this is a good place to configure the browser environment for production or development.

    polyfills.ts我们需要polyfill在大多数浏览器中运行Angular应用程序,如浏览器支持指南中所述。 该捆绑文件将首先加载,因此这是为生产或开发配置浏览器环境的好地方。

Create a new config folder and the following files inside:

创建一个新的config文件夹,并在其中包含以下文件:

  • webpack.config.common.js : configuration that we will use for development and production.

    webpack.config.common.js :我们将用于开发和生产的配置。

Entry — For this application (and for most of them actually) we have 3 different entry points : vendor.ts polyfills.ts and main.ts.

入口-对于这种应用(和大部分其实)我们有3个不同的切入点: vendor.ts polyfills.tsmain.ts.

entry: {
    vendor: './src/vendor.ts',
    polyfills: './src/polyfills.ts',
    main: './src/main.ts'
}

Loaders — We load .html files with html-loader which is pretty standard. Loading .scss files is a bit tricky for an Angular app and I struggled for many hours to figure out how to do it.

html-loader -我们使用标准的html-loader加载.html文件。 对于Angular应用程序来说,加载.scss文件有点棘手,我花了好几个小时努力弄清楚该怎么做。

First of all, we must load sass files by using two loaders sass-loader and css-loader. If you want to make debugging easy, especially in development mode, it’s really important to add sourceMap: true as options. In an Angular application we add styles to component by passing a file path to styleUrls array as follow styleUrls: ["./path/styles.scss"] but we need to have style as a string and to-string-loader will do it for us and cast the output to a string.

首先,我们必须使用两个装载程序sass-loadercss-loader.来装载sass文件css-loader. 如果要sourceMap: true调试,尤其是在开发模式下,则添加sourceMap: true非常重要sourceMap: true 作为选择。 在Angular应用程序中,我们通过将文件路径传递给styleUrls数组,如下所示,将样式添加到组件中styleUrls: ["./path/styles.scss"]但是我们需要将样式作为字符串,并且to-string-loader将做到这一点对我们来说,将输出转换为字符串。

{
    test: /\.html$/,
    loader: 'html-loader'
},
{
    test: /\.(scss|sass)$/,
    use: [
        'to-string-loader',
        { 
            loader: 'css-loader', 
            options: { 
                sourceMap: true 
            } 
        },
        { 
            loader: 'sass-loader', 
            options: { 
                sourceMap: true 
            } 
        }
    ],
    include: helpers.root('src', 'app')
}

Plugins — CleanWebpackPlugin will remove/clean your build folder(s) before building again. HtmlWebpackPlugin plugin will generate an HTML5 file for you that includes all your webpack bundles in the body using script tags. It only requires path to the template.

插件 CleanWebpackPlugin将在重新构建之前删除/清除您的构建文件夹。 HtmlWebpackPlugin插件将使用脚本标签为您生成一个HTML5文件,其中包括您体内的所有webpack捆绑包。 它只需要模板的路径。

new CleanWebpackPlugin(
    helpers.root('dist'),
    {
        root: helpers.root(),
        verbose: true
    }
),
new HtmlWebpackPlugin({
    template: 'src/index.html'
})
  • webpack.config.dev.js is our webpack configuration that we will use for development mode only.

    webpack.config.dev.js是我们的webpack配置,仅用于开发模式。

mode: "development"

In webpack 4, chosen mode tells webpack to use its built-in optimizations accordingly.

在webpack 4中,选择的模式告诉webpack相应地使用其内置优化。

devtool: 'cheap-module-eval-source-map'

This option controls if and how source maps are generated. By using cheap-module-eval-source-map Source Maps from loaders are processed for better results. However, loader Source Maps are simplified to a single mapping per line.

此选项控制是否以及如何生成源映射。 通过使用cheap-module-eval-source-map处理来自加载程序的Source Map,以获得更好的结果。 但是,加载程序源映射简化为每行一个映射。

output: {
    path: helpers.root('dist'),
    publicPath: '/',
    filename: '[name].bundle.js',
    chunkFilename: '[id].chunk.js'
}

The output key contains a set of options instructing webpack on how and where it should output your bundles, assets and anything else you bundle or load with webpack. Here we tell webpack to output our bundles to the dist folder.

output键包含一组选项,这些选项指示webpack如何以及在何处输出捆绑包,资产以及您通过webpack捆绑或加载的其他任何内容。 在这里,我们告诉webpack将包输出到dist文件夹。

optimization: {
    noEmitOnErrors: true
}

Skips the emitting phase whenever there are errors while compiling. This ensures that no erroring assets are emitted. The optimization key has many others options that are set by default depending on your webpack configuration mode (development/production). You can read more about it here.

编译时只要有错误就跳过发射阶段。 这样可以确保不会发出错误的资产。 optimization密钥还有许多其他选项,这些选项默认设置,具体取决于您的Webpack配置模式(开发/生产)。 您可以在此处了解更多信息。

{
    test: /\.ts$/,
    loaders: [
        'babel-loader',
        {
            loader: 'awesome-typescript-loader',
            options: {
                configFileName: helpers.root('tsconfig.json')
            }
        },
        'angular2-template-loader',
        'angular-router-loader'
    ],
    exclude: [/node_modules/]
}

angular-router-loader is a webpack loader that enables string-based module loading with the Angular Router.

angular-router-loader是一个webpack加载器,可通过Angular Router加载基于字符串的模块。

angular2-template-loader is a chain-to loader that inlines all html and styles in Angular components.

angular2-template-loader是一个链接到加载器,可以内联Angular组件中的所有html和样式。

awesome-typescript-loader is currently the faster webpack TypeScript loader. It uses dependency resolution to build modules dependency graph. This relatively speeds up the build process.

awesome-typescript-loader typescript awesome-typescript-loader当前是速度更快的webpack TypeScript加载器。 它使用依赖关系解析来构建模块依赖关系图。 这相对加快了构建过程。

babel-loader allows transpiling JavaScript files.

babel-loader允许转储JavaScript文件。

devServer: {
    historyApiFallback: true,
    stats: 'minimal'
}

When using the HTML5 History API, the index.html page will likely have to be served in place of any 404 responses. For that we need to enable historyApiFallback.

使用HTML5历史记录API时 ,可能必须提供index.html页面来代替任何404响应。 为此,我们需要启用historyApiFallback.

stats option lets you precisely control what bundle information gets displayed. This can be a nice middle ground if you want some bundle information, but not all of it.

stats选项使您可以精确控制显示哪些捆绑软件信息。 如果您需要一些捆绑软件信息,但又不是全部,这可能是很好的中间立场。

添加脚本 (Adding scripts)

Add the following lines to your package.json file:

package.json添加到package.json文件:

"scripts": {
  "build:dev": "webpack-dev-server --inline --hot --progress --port 8080"
}

--hot enables webpack Hot Module Replacement (HMR). It exchanges, adds, or removes modules while an application is running, without a full reload. This can significantly speed up development in a few ways:

--hot启用webpack热模块更换(HMR)。 它在应用程序运行时交换,添加或删除模块 ,而无需完全重新加载。 这可以通过以下几种方式显着加快开发速度:

  • Retain application state which is lost during a full reload.

    保留在完全重载期间丢失的应用程序状态。
  • Save valuable development time by only updating what’s changed.

    仅更新更改内容即可节省宝贵的开发时间。
  • Modifications made to CSS/JS in the source code results in an instant browser update which is almost comparable to changing styles directly in the browser’s dev tools.

    在源代码中对CSS / JS进行的修改会导致浏览器即时更新,几乎可以与直接在浏览器的dev工具中更改样式相提并论。

Now you are all setup! You can run npm run build:dev open your browser and navigate to localhost:8080.

现在,您已经完成所有设置! 您可以运行npm run build:dev打开浏览器并导航到localhost:8080.

用于生产模式的Webpack配置(提前编译) (Webpack configuration for production mode (Ahead-of-Time compilation))

AoT编译的优点 (Advantages of AoT compilation)

  • With AoT, the browser downloads a pre-compiled version of the application. The browser loads executable code so it can render the application immediately, without waiting to compile the app first.

    使用AoT,浏览器可以下载该应用程序的预编译版本。 浏览器加载可执行代码,因此它可以立即呈现应用程序,而无需等待首先编译应用程序。
  • The compiler inlines external HTML templates and CSS style sheets within the application JavaScript, eliminating separate AJAX requests for those source files.

    编译器在应用程序JavaScript中内联外部HTML模板和CSS样式表,从而消除了对那些源文件的单独AJAX请求。
  • There’s no need to download the Angular compiler if the app is already compiled. The compiler is roughly half of Angular itself, so omitting it dramatically reduces the application payload.

    如果该应用程序已经编译,则无需下载Angular编译器。 编译器大约是Angular本身的一半,因此省略编译器会大大减少应用程序的有效负载。
  • The AoT compiler detects and reports template binding errors during the build step before users can see them.

    在用户看到它们之前,AoT编译器会在构建步骤中检测并报告模板绑定错误。
  • AoT compiles HTML templates and components into JavaScript files long before they are served to the client. With no templates to read and no risky client-side HTML or JavaScript evaluation, there are fewer opportunities for injection attacks.

    AoT在将HTML模板和组件提供给客户端之前就已经将它们编译为JavaScript文件。 没有要读取的模板,没有风险的客户端HTML或JavaScript评估,注入攻击的机会就更少了。

配置Webpack (Configuring webpack)

In your config folder create a new file webpack.config.prod.js

在您的config文件夹中创建一个新文件webpack.config.prod.js

mode: 'production'

We usually proceed to AoT compilation in production mode and, as I wrote previously, in webpack 4, chosen mode tells webpack to use its built-in optimizations accordingly.

我们通常在生产模式下进行AoT编译,正如我之前写的那样,在webpack 4中,选择的模式告诉webpack相应地使用其内置优化。

output: {
    path: helpers.root('dist'),
    publicPath: '/',
    filename: '[hash].js',
    chunkFilename: '[id].[hash].chunk.js'
}

We also tell webpack to output our bundles to the dist folder. We include a hash to the file names to leverage client level cache efficiently. This way webpack knows whether or not a file has changed. Webpack provides placeholders for this purpose. These strings are used to attach specific information to outputs. The most valuable ones are:

我们还告诉webpack将我们的包输出到dist文件夹。 我们在文件名中包含哈希,以有效利用客户端级别的缓存。 Webpack通过这种方式知道文件是否已更改。 Webpack为此提供了占位符 。 这些字符串用于将特定信息附加到输出。 最有价值的是:

  • [id] returns the chunk id.

    [id]返回块ID。

  • [path] returns the file path.

    [path]返回文件路径。

  • [name] returns the file name.

    [name]返回文件名。

  • [ext] returns the extension. [ext] works for most available fields.

    [ext]返回扩展名。 [ext]适用于大多数可用字段。

  • [hash] returns the build hash. If any portion of the build changes, this changes as well.

    [hash]返回构建哈希。 如果构建的任何部分发生更改,则此更改也将更改。

  • [chunkhash] returns an entry chunk-specific hash. Each entry defined in the configuration receives a hash of its own. If any portion of the entry changes, the hash will change as well. [chunkhash] is more granular than [hash] by definition.

    [chunkhash]返回特定于条目块的哈希。 配置中定义的每个entry接收自己的哈希。 如果条目的任何部分发生更改,则哈希也将更改。 根据定义, [chunkhash][hash]更细。

  • [contenthash] returns a hash generated based on content.

    [contenthash]返回基于内容生成的哈希。

It’s preferable to use particularly hash and chunkhash only for production as hashing is not essential during development.

最好仅将hashchunkhash hash仅用于生产,因为在开发过程中哈希不是必需的。

optimization: {
    noEmitOnErrors: true,
    splitChunks: {
        chunks: 'all'
    },
    runtimeChunk: 'single',
    minimizer: [
        new UglifyJsPlugin({
            cache: true,
            parallel: true
        }),
        
         new OptimizeCSSAssetsPlugin({
             cssProcessor: cssnano,
             cssProcessorOptions: {
                 discardComments: {
                     removeAll: true
                 }
             },
             canPrint: false
         })
    ]
}
  • As in development mode, we want to skip the emitting phase whenever there are errors while compiling. This ensures that no erroring assets are emitted.

    与开发模式一样,我们希望在编译时出现错误时跳过发射阶段。 这样可以确保不会发出错误的资产。
  • chunks: ‘all’ indicates which chunks will be selected for optimization. Providing all can be particularly powerful, because it means that chunks can be shared even between async and non-async chunks.

    chunks: 'all'指示将选择哪些块进行优化。 提供all功能特别强大,因为这意味着即使在异步和非异步块之间也可以共享块。

  • Imported modules are initialized for each runtime chunk separately. As webpack suggests, while working on a project with multiple entry points you want to have only one runtime instance. For that you need to set it to ‘single’.

    分别为每个运行时块初始化导入的模块。 正如webpack所建议的那样,在处理具有多个入口点的项目时,您只希望有一个运行时实例。 为此,您需要将其设置为'single'

  • UglifyJsPlugin uses uglify-js to minify your JavaScript files. We set cache and parallel properties to true in order to enable file caching and to use multi-process parallel running to improve the build speed. There are more options available and I invite you to learn more about this plugin.

    UglifyJsPlugin使用UglifyJsPlugin -js来最小化您JavaScript文件。 我们将cacheparallel属性设置为true以便启用文件缓存并使用多进程并行运行来提高构建速度。 有更多可用选项,我邀请您进一步了解此插件

  • OptimizeCSSAssetsPlugin will search for CSS assets during the webpack build and will optimize and minimize it. The CSS processor used for optimization is cssnano. All comments will be removed from our minified CSS and no messages will be print to the console.

    OptimizeCSSAssetsPlugin将在Webpack构建期间搜索CSS资产,并将其优化和最小化。 用于优化CSS处理器是cssnano. 所有评论将从我们缩小CSS中删除,并且不会将任何消息打印到控制台。

module: {
    rules: [
        {
            test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
            loader: '@ngtools/webpack'
        }
    ]
}

plugins: [
    new ngw.AngularCompilerPlugin({
        tsConfigPath: helpers.root('tsconfig.aot.json'),
        entryModule: helpers.root('src', 'app', 'modules', 'app', 'app.module#AppModule')
    })
]

@ngtools/webpack is the official plugin that AoT compiles your Angular components and modules. The loader works with webpack plugin to compile your TypeScript. It’s important to include both, and to not include any other TypeScript compiler loader.

@ngtools/webpack是AoT编译Angular组件和模块的官方插件。 加载程序与webpack插件一起编译您的TypeScript。 重要的是要同时包含两者,并且不包含任何其他TypeScript编译器加载器。

添加main.aot.ts文件 (Adding main.aot.ts file)

In the src folder add main.aot.ts file:

src文件夹中添加main.aot.ts文件:

import { enableProdMode } from '@angular/core';
import { platformBrowser } from '@angular/platform-browser';

import { AppModuleNgFactory } from './app/app.module.ngfactory';

enableProdMode();

platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);

Your main entry is a bit different in production mode and AoT compilation:

您的main条目在生产模式和AoT编译中有些不同:

  • Import enableProdMode to disable Angular’s development mode, which turns off assertions and other checks within the framework.

    导入enableProdMode以禁用Angular的开发模式,该模式将关闭框架中的断言和其他检查。

  • Import platformBrowser AND NOT platformBrowserDynamic because in AoT compilation your application is shipped to the browser already compiled whereas in JiT compilation it occurs at the browser level.

    导入platformBrowser 不是 platformBrowserDynamic因为在AoT编译中,您的应用程序已交付给已经编译的浏览器,而在JiT编译中,它发生在浏览器级别。

  • Instead of importing AppModule you need to import AppModuleFactory which is your compiled application generated by our Angular compiler.

    无需导入AppModule您需要导入AppModuleFactory ,这是由Angular编译器生成的已编译应用程序。

添加脚本 (Adding scripts)

Add the following scripts to your package.json file :

将以下脚本添加到package.json文件:

"webpack-prod": "cross-env NODE_ENV=production webpack --mode production"

"build:prod": "npm run build:clean && ngc && npm run webpack-prod && npm run build:clean"

"build:clean": "del-cli 'src/**/*.js' 'src/**/*.js.map' 'src/**/*.ngsummary.json' 'src/**/*.metadata.json' 'src/**/**/*.ngfactory.ts' 'src/**/*.ngstyle.ts' 'src/**/*.shim.ts'"

"serve": "lite-server"
  • build:clean: the Angular compiler generates many files in order to compile your application. To stay clean in our project, we delete all these files before compilation and after generating bundles.

    build:clean :Angular编译器生成许多文件来编译您的应用程序。 为了保持项目干净,我们在编译之前和生成捆绑包后删除了所有这些文件。

  • build:prod: run the Angular compiler with ngc command and then run webpack in production mode to generate your bundles.

    build:prod :使用ngc命令运行Angular编译器,然后在生产模式下运行webpack生成捆绑包。

  • serve: I use lite-server to serve our application and see what it looks like. Of course, you won’t need it in a real world project because your app will be serve by the cloud.

    serve :我使用lite-server服务我们的应用程序,然后看它看起来像什么。 当然,在现实世界的项目中您将不需要它,因为您的应用程序将由云服务。

Now, you can run npm run build:prod to compile your Angular application and build your bundles. Then, run npm run serve to serve your app to the browser.

现在,您可以运行npm run build:prod来编译Angular应用程序并生成捆绑包。 然后,运行npm run serve将您的应用程序提供给浏览器。

I hope you enjoyed this article! If you have any questions/suggestions, let me know in the comments below.

希望您喜欢这篇文章! 如果您有任何疑问/建议,请在下面的评论中告诉我。

The project files are on my GitHub:

项目文件在我的GitHub上:

samteb/Angular-7-Webpack-4Contribute to samteb/Angular-7-Webpack-4 development by creating an account on GitHub.github.co

samteb / Angular-7-Webpack-4 通过在GitHub上创建一个帐户来为samteb / Angular-7-Webpack-4开发做出贡献。 github.co

翻译自: https://www.freecodecamp.org/news/how-to-configure-webpack-4-with-angular-7-a-complete-guide-9a23c879f471/

 类似资料: