ExtractTextPlugin不适用于角AOT构建

ExtractTextPlugin不适用于角AOT构建

问题描述:

所以我想创建一个Angular(4.4.4)Webpack(3.6.0)初学者与AOT构建,我遇到了一个问题,提取到一个单独的捆绑的CSS(使用extract- text-webpack-plugin 3.0.1)。ExtractTextPlugin不适用于角AOT构建

当我运行我的prod构建webpack构建卡住在95% emitting。它永远不会达到100%,并且永远不会输出dist包。起初,我尝试使用style-loader0.19.0)创建内联CSS,但这并不成功,因为Angular AOT构建在构建过程中没有窗口对象(此时sass-loader会失败)。由于这个原因,我不得不在生产过程中将css解压为一个独立的包(不是一件坏事)。

但不知何故,编译器失速并从未给出错误。

webpack.common.js

module.exports = { 
    entry: { 
     app: './src/main.ts', 
     vendor: getVendorPackages() 
    }, 
    output: { 
     path: __dirname + '/dist', 
     filename: "website.bundle.js" 
    }, 
    module: { 
     rules: [ 
      { 
       test: /\.html$/, 
       loader: 'html-loader' 
      } 
     ] 
    }, 
    plugins: [ 
     new webpack.ContextReplacementPlugin(//Resolve Angular warnings 
      /angular(\\|\/)core(\\|\/)@angular/, 
      path.resolve(__dirname, '../src') 
     ), 
     new webpack.optimize.CommonsChunkPlugin({ //Create secondary bundle containing dependencies 
      name: 'vendor', 
      filename: 'vendor.bundle.js', 
      minChunks(module) { 
       const context = module.context; 
       return context && context.indexOf('node_modules') >= 0; 
      }, 
     }), 
     new htmlWebpackPlugin({ //Generate index.html 
      template: './src/index.html' 
     }), 
     new webpack.ContextReplacementPlugin(//Only export the locals we need | https://github.com/moment/moment/issues/2517 
      /moment[\/\\]locale$/, /en|nl/ 
     ) 
    ], 
    resolve: { 
     extensions: ['.js', '.ts', '.scss'] 
    } 
}; 

Webpack.prod.js

module.exports = merge(common, { 
    module: { 
     rules: [ 
      { 
       test: /\.ts$/, 
       loaders: ['@ngtools/webpack'] 
      }, 
      { 
       test: /\.scss$/, 
       use: ExtractTextPlugin.extract({ // Fallback is not necessary, since style-loader will fail with AOT build 
        use: ["css-loader", "sass-loader"] 
       }) 
      } 
     ] 
    }, 
    plugins: [ 
     new webpack.optimize.UglifyJsPlugin({ // Uglyfy the JavaScript output 
      beautify: false, 
      mangle: { 
       screw_ie8: true, 
       keep_fnames: true 
      }, 
      compress: { 
       warnings: false, 
       screw_ie8: true 
      }, 
      comments: false 
     }), 
     new AotPlugin({ // Create AOT build 
      tsConfigPath: './tsconfig.json', 
      entryModule: __dirname + '/src/app/app.module#AppModule' 
     }), 
     new webpack.DefinePlugin({ // Set the node env so that the project knows what to enable or disable 
      'process.env': { 
       'NODE_ENV': JSON.stringify('production') 
      } 
     }), 
     new ExtractTextPlugin("styles.css") //Create an external style bundle 
    ] 
}); 

对于我运行下面的NPM任务督促编译:"build --prod": "webpack -p --config webpack.prod.js --progress"

我的的package.json依赖看起来是这样的:

"dependencies": { 
    "@angular/common": "4.4.4", 
    "@angular/compiler": "4.4.4", 
    "@angular/core": "4.4.4", 
    "@angular/forms": "4.4.4", 
    "@angular/http": "4.4.4", 
    "@angular/platform-browser": "4.4.4", 
    "@angular/platform-browser-dynamic": "4.4.4", 
    "@angular/router": "4.4.4", 
    "core-js": "2.5.1", 
    "reflect-metadata": "0.1.10", 
    "rxjs": "5.4.3", 
    "zone.js": "0.8.18" 
    }, 
    "devDependencies": { 
    "@angular/compiler-cli": "4.4.4", 
    "@ngtools/webpack": "1.7.2", 
    "@types/core-js": "0.9.43", 
    "@types/node": "8.0.31", 
    "angular2-template-loader": "0.6.2", 
    "awesome-typescript-loader": "3.2.3", 
    "codelyzer": "3.2.0", 
    "css-loader": "0.28.7", 
    "extract-text-webpack-plugin": "3.0.1", 
    "html-loader": "0.5.1", 
    "html-webpack-plugin": "2.30.1", 
    "node-sass": "4.5.3", 
    "sass-loader": "6.0.6", 
    "style-loader": "0.19.0", 
    "tslint": "5.7.0", 
    "typescript": "2.5.3", 
    "webpack": "3.6.0", 
    "webpack-bundle-analyzer": "2.9.0", 
    "webpack-dev-server": "2.9.1", 
    "webpack-merge": "4.1.0" 
    } 

角度成分如下:

@Component({ 
    selector: 'hn-root', 
    templateUrl: './app.html', 
    styleUrls: ['./app.scss'], 
}) 
export class AppComponent { 
} 

而且我项目结构是:

- src 
    -- app 
    -- app.component.ts 
    -- app.html 
    -- app.module.ts 
    -- app.scss 
    index.html 
    main.ts 

任何人都知道我在做什么错?

在阅读了Angular的更多关于视图封装之后,我现在知道你不应该在Angular中使用style-loader。

Style-loader很好,如果你想拥有全局样式,但是当你想要只适用于包含它们的组件的样式,那么你应该使用raw-loader

所以添加原装载机(npm install --save-dev raw-loader)后,我改变了我的webpack.prod.js到:

module.exports = merge(common, { 
    module: { 
     rules: [ 
      { 
       test: /\.ts$/, 
       loaders: ['@ngtools/webpack'] 
      }, 
      { 
       test: /\.scss$/, 
       exclude: /node_modules/, 
       loaders: ['raw-loader', 'sass-loader'] 
      } 
     ] 
    }, 
    plugins: [ 
     new webpack.optimize.UglifyJsPlugin({ // Uglyfy the JavaScript output 
      beautify: false, 
      mangle: { 
       screw_ie8: true, 
       keep_fnames: true 
      }, 
      compress: { 
       warnings: false, 
       screw_ie8: true 
      }, 
      comments: false 
     }), 
     new AotPlugin({ // Create AOT build 
      tsConfigPath: './tsconfig.json', 
      entryModule: __dirname + '/src/app/app.module#AppModule' 
     }), 
     new webpack.DefinePlugin({ // Set the node env so that the project knows what to enable or disable 
      'process.env': { 
       'NODE_ENV': JSON.stringify('production') 
      } 
     }) 
    ] 
}); 

这样我可以使用视图封装像角建议(这也是如何角-cli做到了)。

来源:

Github - AngularClass

Github - Angular starter