简体   繁体   English

如何防止Angular AOT Webpack插件编译TypeScript代码块

[英]How to prevent TypeScript code blocks from being compiled by the Angular AOT Webpack plugin

I want to exclude some code from being compiled by Angular's AOT compiler. 我想从Angular的AOT编译器中排除一些代码。 For example, the webpack-strip-block loader can be used to remove code between comments in production. 例如,可使用webpack-strip-block加载器删除生产中注释之间的代码。

export class SomeComponent implements OnInit {
  ngOnInit() {
    /* develblock:start */
    alert("Show in development only"); // Oops. This still appears in production.
    /* develblock:end */
  }
}

More specifically, I'm trying to exclude an entire NgModule (eg TestModule) from being compiled. 更具体地说,我试图从编译中排除整个NgModule(例如TestModule)。 One way to do this would be to remove the line(s) in the app-routing.module that create the route. 一种方法是在app-routing.module中删除创建路由的行。 For example: 例如:

// app-routing.module
const routes: Routes = [
 {
    /* develblock:start */
    path: 'test', loadChildren: './test/test.module#TestModule'
    /* develblock:end */
 }
]

// webpack.config.js 
{
    test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
    use: [
      { loader: '@ngtools/webpack' },
      { loader: 'webpack-strip-block' }
    ]
}

Note: This isn't a specific question about the webpack-strip-block plugin. 注意:这不是关于webpack-strip-block插件的特定问题。 I'm just using the plugin as an example because it makes my intent clear. 我只是以该插件为例,因为它可以使我的意图明确。 The plugin's author has already stated that he doesn't expect the plugin to work with the AngularCompilerPlugin. 该插件的作者已经声明他不希望该插件与AngularCompilerPlugin一起使用。 The plugin does work with my CSS files, but that's beside the point. 该插件我的CSS文件的工作,但是这不是重点。

Here are some other things that I've tried: 这是我尝试过的其他方法:

1. Using Webpack exclude (or include). 1.使用Webpack排除(或包括)。 Nope. 不。 Excluding the folder throws compiler errors because the application code still depends on TestModule. 排除文件夹会引发编译器错误,因为应用程序代码仍取决于TestModule。

{
  test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
  loader: '@ngtools/webpack',
  exclude: path.resolve(__dirname, 'src/app/test')
},

2. Using NODE_ENV to conditionally load the route. 2.使用NODE_ENV有条件地加载路由。 Nope. 不。 Compiler errors galore because an if statement is (obviously) not allowed inside an array of objects. 编译器错误非常多,因为(显然)在对象数组内不允许使用if语句。

const routes: Routes = [{
  if (process.env.NODE_ENV !== 'production') {
    path: 'test', loadChildren: './test/test.module#TestModule'
  }
}];

3. Using Webpack Externals . 3.使用Webpack外部 I've tried it, but it doesn't seem appropriate for this use case. 我已经尝试过了,但似乎不适用于此用例。

Here's my dependency list: 这是我的依赖项列表:

Angular 6.1.7 角6.1.7
TypeScript 2.9.2 TypeScript 2.9.2
Webpack 4.19.1 Webpack 4.19.1

You can use DefinePlugin to create a global replacement for var NODE_ENV (for example): 您可以使用DefinePlugin创建var NODE_ENV的全局替换(例如):

// inside webpack.config
plugins: [
    new webpack.DefinePlugin({
        NODE_ENV: JSON.stringify(process.env.NODE_ENV)
    })
]

Then you can use this var like this: 然后,您可以像下面这样使用该变量:

declare const NODE_ENV: string;

if (NODE_ENV !== 'production') {
    routes.push({ path: 'test', loadChildren: './test/test.module#TestModule' });
}

Webpack will replace NODE_ENV with the actual value. Webpack将用实际值替换NODE_ENV。 In production it will be 'production' so the code inside the if ('production' !== 'production') will be unreachable and AOT will remove it. 在生产中将是'production'因此if ('production' !== 'production')将无法访问,AOT会将其删除。

In Webpack 4 you can conditionally add a route in app-routing.module using NODE_ENV: 在Webpack 4中,您可以使用NODE_ENV有条件地在app-routing.module中添加路由:

if (process.env.NODE_ENV === 'development') {
  routes.push({ path: 'test', loadChildren: './test/test.module#TestModule' });
}

This prevents TestModule from being compiled in production. 这样可以防止TestModule在生产中被编译。 Thanks to Pavel Agarkov for the suggestion to push the route object onto the array. 感谢Pavel Agarkov提出的将路线对象推入阵列的建议。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM