Angular4 + AoT和两个带有公共代码的项目导致重复声明错误

时间:2017-07-17 17:25:35

标签: angular webpack-2 angular2-aot

我有一个我开发的Angular4项目,该项目分为两个主要项目:大多数最终用户点击的主要应用程序和特权用户点击的管理应用程序。这些应用程序共享一些通用代码。这是一般文件夹结构:

-src
  -app
    -common (contains several subfolders for utilities, pipes, models, etc.)
    -main (contains the main angular4 app with associated module, route, and lazy loaded component files)
    -management (contains the management angular4 app with associated module, route, and lazy loaded component files)

我正在使用webpack2来打包项目,并且所有内容都在使用JiT编译时运行良好,但现在我正在尝试启用AoT,但由于重复声明我遇到错误:

Error: Type OrderByPipe in W:/MyApp/src/app/common/pipes/orderBy.ts is part of the declarations of 2 modules: 
SharedModule in W:/MyApp/src/app/main/shared.module.ts and SharedModule in W:/MyApp/src/app/management/shared.module.ts!
Please consider moving OrderByPipe in W:/MyApp/src/app/common/pipes/orderBy.ts to a higher module that imports SharedModule in W:/MyApp/src/app/main/shared.module.ts and SharedModule in W:/MyApp/src/app/management/shared.module.ts.
You can also create a new NgModule that exports and includes OrderByPipe in W:/MyApp/src/app/common/pipes/orderBy.ts then import that NgModule in SharedModule in W:/MyApp/src/app/main/shared.module.ts and SharedModule in W:/MyApp/src/app/management/shared.module.ts

在这种情况下,OrderByPipe在我的公共文件夹中定义。这两个项目仅指向共享公共代码,它们之间没有任何关联。我在我的webpack配置中有排除项,以防止(我假设)一个项目查看另一个项目中的文件,但看起来它不像我期望的那样工作?这是我主要项目的webpack配置:

var webpack = require('webpack');
var ngToolsWebpack = require('@ngtools/webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var helpers = require('./helpers');
require('es6-promise').polyfill();

module.exports = {
    devtool: 'inline-source-map',
    entry: {
        MyAppApp: './src/app/main/main.ts',
        polyfills: './src/app/main/polyfills.ts',
        vendor: './src/app/main/vendor.ts'
    },
    resolve: {
        extensions: ['.ts', '.js']
    },
    module: {
        rules: [
            {
                test: /\.ts$/,
                exclude: [helpers.root('src', 'app/management'), helpers.root('src', 'app/host')],
                use: [{ loader: '@ngtools/webpack' }, { loader: 'angular-router-loader' }]
            },
            {   test: /\.html$/,
                exclude: [helpers.root('src', 'app/management'), helpers.root('src', 'app/host')],
                use: [{ loader: 'html-loader' }]
            },
            {
                test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
                exclude: [helpers.root('src', 'app/management'), helpers.root('src', 'app/host')],
                use: [{ loader: 'file-loader?name=images/[name].[ext]' }]
            },
            {
                test: /myapp-main-core\.scss$/,
                include: helpers.root('src', 'app/css'),
                use: ExtractTextPlugin.extract({ use: [{ loader: "css-loader?sourceMap" }, { loader: "sass-loader?sourceMap" }] })
            },
            {
                test: /\.scss$/,
                exclude: [helpers.root('src', 'app/management'), helpers.root('src', 'app/host'), helpers.root('src', 'app/css')],
                use: ['to-string-loader'].concat(ExtractTextPlugin.extract({ 
                    fallback: 'style-loader',
                    use: ['css-loader?sourceMap', 'sass-loader?sourceMapp'] }))
            }
        ]
    },

    output: {
        path: helpers.root('app'),
        publicPath: 'https://localhost:8080/app/',
        filename: 'js/[name].js?[hash]-' + process.env.buildNumber,
        chunkFilename: 'js/MyAppApp-[id].chunk.js?[hash]-' + process.env.buildNumber
    },

    plugins: [
        new webpack.optimize.CommonsChunkPlugin({
            name: ['MyAppApp', 'vendor', 'polyfills']
        }),
        new HtmlWebpackPlugin({
            template: 'src/app/main/index.html'
        }),
        new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
        new ExtractTextPlugin('./css/myapp-main-core.css'),
        new webpack.ContextReplacementPlugin(
            /angular(\\|\/)core(\\|\/)@angular/,
            helpers.root('doesnotexist')
        ),
        new ngToolsWebpack.AotPlugin({
            tsConfigPath: './tsconfig.json',
            entryModule: './src/app/main/app.module#AppModule'
        })
    ]
};

当我明确地从webpack配置中排除它的文件夹时,我不知道为什么这个过程正在考虑管理应用程序。我敢肯定我错过了一些明显但没有线索的东西。

非常感谢任何帮助!

更新7/17/2017: 我创建了一个新的tsconfig.json文件(tsconfig.main.aot.json)并为其中的管理目录添加了一个排除项,然后将webpack配置指向AoTPlugin配置中的该文件,这似乎已经超过了重复声明错误我看到了,但现在我遇到了extract-text-webpack-plugin的问题,所以我猜我的AoT如何配置有问题:

Module build failed: Error: "extract-text-webpack-plugin" loader is used without the corresponding plugin

1 个答案:

答案 0 :(得分:0)

当我在两个不同的模块中向pipe添加一个component时,我收到此错误,因此这可能是因为它是两个不同的ptoject。我经常做的诀窍是创建一个新的*.module.ts文件并导入该组件或者哪一件事给它带来麻烦;然后将新模块导入到您想要的任何位置。

@NgModule({
  imports: [CommonModule],
  declarations: [
    YouComponent
  ],
  exports: [
    YouComponent
  ],
  providers: []
})

export class commonsModule {}