├── .gitignore
├── superstatic.json
├── src
├── favicon.ico
├── app
│ ├── dynamicModule
│ │ ├── dy1.component.ts
│ │ ├── dy2.component.ts
│ │ ├── dynamicModule.template.html
│ │ ├── comMgr.ts
│ │ ├── dynamicModule.scss
│ │ ├── dynamicModule-routing.module.ts
│ │ ├── dynamicModule.module.ts
│ │ └── dynamic.component.ts
│ ├── app.component.html
│ ├── app.component.ts
│ ├── core
│ │ └── core.module.ts
│ ├── app-routing.module.ts
│ ├── app.component.scss
│ ├── shared
│ │ └── shared.module.ts
│ └── app.module.ts
├── main.ts
├── polyfills.ts
├── index.html
├── vendor.ts
└── assets
│ └── styles
│ └── index.scss
├── webpack.config.js
├── README.md
├── config
├── helpers.js
├── webpack.dev.js
├── webpack.prod.js
└── webpack.common.js
├── tsconfig.json
└── package.json
/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules/*
2 | /dist/*
3 | /.idea/
--------------------------------------------------------------------------------
/superstatic.json:
--------------------------------------------------------------------------------
1 | {
2 | "rewrites": [
3 | {"source":"/*", "destination":"/index.html"}
4 | ]
5 | }
--------------------------------------------------------------------------------
/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wuzhouyang/angular-dynamic-component-example/HEAD/src/favicon.ico
--------------------------------------------------------------------------------
/src/app/dynamicModule/dy1.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core'
2 |
3 | @Component({
4 | template:`动态组件1`
5 | })
6 | export class DY1Component{}
--------------------------------------------------------------------------------
/src/app/dynamicModule/dy2.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core'
2 |
3 | @Component({
4 | template:`动态组件2`
5 | })
6 | export class DY2Component{}
--------------------------------------------------------------------------------
/src/app/app.component.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
--------------------------------------------------------------------------------
/src/app/dynamicModule/dynamicModule.template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | switch (process.env.NODE_ENV) {
2 | //生产模式(aot)
3 | case 'prod':
4 | module.exports = require('./config/webpack.prod.js');
5 | break;
6 | //开发模式
7 | case 'dev':
8 | default:
9 | module.exports = require('./config/webpack.dev.js');
10 | }
--------------------------------------------------------------------------------
/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component} from '@angular/core'
2 |
3 | @Component({
4 | selector: 'wzy-app',
5 | templateUrl: './app.component.html',
6 | styleUrls:[
7 | './app.component.scss'
8 | ]
9 | })
10 | export class AppComponent{
11 | public constructor() {}
12 | }
--------------------------------------------------------------------------------
/src/app/dynamicModule/comMgr.ts:
--------------------------------------------------------------------------------
1 | import { DY1Component } from './dy1.component'
2 | import { DY2Component } from './dy2.component'
3 |
4 | let coms={
5 | DY1Component,
6 | DY2Component
7 | }
8 | const importComs = [
9 | DY1Component,
10 | DY2Component
11 | ]
12 |
13 | export { coms, importComs }
--------------------------------------------------------------------------------
/src/app/dynamicModule/dynamicModule.scss:
--------------------------------------------------------------------------------
1 | .dm{
2 | width: 50%;
3 | margin: auto;
4 | .dmBtn{
5 | background: rgba(255,255,255,.3);
6 | color:#fff;
7 | border:none;
8 | outline: none;
9 | padding: 10px;
10 | }
11 | .dmRoom{
12 | margin-top: 10px;
13 | }
14 | }
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | //主入口文件
2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'
3 | import { enableProdMode } from '@angular/core'
4 |
5 | import { AppModule } from './app/app.module'
6 |
7 | import './assets/styles/index.scss'
8 |
9 | enableProdMode()
10 | platformBrowserDynamic().bootstrapModule(AppModule)
--------------------------------------------------------------------------------
/src/polyfills.ts:
--------------------------------------------------------------------------------
1 | //填充物
2 | import 'core-js/es6'
3 | import 'core-js/es7/reflect'
4 | import 'zone.js/dist/zone'
5 | if (process.env.NODE_ENV === 'prod' || process.env.NODE_ENV === 'aot') {
6 | // Production
7 | } else {
8 | // Development
9 | Error['stackTraceLimit'] = Infinity
10 | require('zone.js/dist/long-stack-trace-zone')
11 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## 动态加载(创建)组件例子
2 |
3 | 简书文章链接:http://www.jianshu.com/p/10feab2c3102
4 |
5 | ## usage of command line 命令行用法
6 | > `npm install`
7 |
8 | > #### develop(port:8111) ---- 开发(端口:8111)
9 | > `npm start`
10 |
11 | > #### aot、production(port:8112) ---- aot编译(端口:8112)
12 | 1. `npm run build`
13 | 2. `npm run server`
14 |
--------------------------------------------------------------------------------
/config/helpers.js:
--------------------------------------------------------------------------------
1 | var path = require('path');
2 | //处理路径 __dirname表示当前文件所在的绝对路径
3 | //_root相当于 当前所在目录的上级
4 | var _root = path.resolve(__dirname, '..');
5 |
6 | //根据传入的参数自动计算路径
7 | function root(args) {
8 | args = Array.prototype.slice.call(arguments, 0);
9 | return path.join.apply(path, [_root].concat(args));
10 | }
11 | exports.root = root;
--------------------------------------------------------------------------------
/src/app/core/core.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule , ModuleWithProviders } from '@angular/core'
2 |
3 | //核心模块,可在此配置全局服务
4 | //core module,you can provide some global services here
5 | @NgModule({
6 | providers:[]
7 | })
8 | export class CoreModule{
9 | static forRoot():ModuleWithProviders{
10 | return{
11 | ngModule:CoreModule
12 | }
13 | }
14 | }
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | 应用加载中(loading)...
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/app/app-routing.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core'
2 | import { Routes, RouterModule } from '@angular/router'
3 |
4 | const routes:Routes=[
5 | {
6 | path:'dynamicModule',
7 | loadChildren:'./dynamicModule/dynamicModule.module#DynamicModule'
8 | }
9 | ]
10 | @NgModule({
11 | imports:[
12 | RouterModule.forRoot(routes)
13 | ],
14 | exports:[
15 | RouterModule
16 | ]
17 | })
18 | export class AppRoutingModule{}
--------------------------------------------------------------------------------
/src/vendor.ts:
--------------------------------------------------------------------------------
1 | //第三方引用
2 | // RxJS
3 | // import 'rxjs';
4 | // import 'rxjs/add/observable/throw'
5 | // import 'rxjs/add/observable/fromEvent'
6 | // import 'rxjs/add/observable/of'
7 | // import 'rxjs/add/operator/do'
8 | // import 'rxjs/add/operator/delay'
9 | // import 'rxjs/add/operator/catch'
10 | // import 'rxjs/add/operator/map'
11 | // import 'rxjs/add/operator/toPromise'
12 | // import 'rxjs/add/operator/distinctUntilChanged'
13 | // import 'rxjs/Subscription'
--------------------------------------------------------------------------------
/src/assets/styles/index.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | html,body{
4 | height:100%;
5 | margin:0;
6 | font-size: 16px;
7 | font-family: "Microsoft YaHei",Serif;
8 | -webkit-font-smoothing: antialiased;
9 | -moz-osx-font-smoothing: grayscale;
10 | }
11 | *{
12 | margin: 0;
13 | padding: 0;
14 | }
15 | .startSpan{
16 | display: block;
17 | width:40%;
18 | margin: auto;
19 | text-align: center;
20 | padding-top: 100px;
21 | padding-bottom:30px;
22 | font-size: 1.8rem;
23 | border-bottom:1px solid #B5B5B5;
24 | }
--------------------------------------------------------------------------------
/src/app/dynamicModule/dynamicModule-routing.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core'
2 | import { Routes,RouterModule } from '@angular/router'
3 |
4 | import { DynamicComponent } from './dynamic.component'
5 | const routes:Routes=[
6 | {
7 | path:'',
8 | component:DynamicComponent
9 | }
10 | ]
11 |
12 | @NgModule({
13 | imports:[
14 | RouterModule.forChild(routes)
15 | ],
16 | exports:[
17 | RouterModule
18 | ]
19 | })
20 | export class DynamicModuleRoutingModule{
21 | }
--------------------------------------------------------------------------------
/src/app/dynamicModule/dynamicModule.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core'
2 |
3 | import { DynamicComponent } from './dynamic.component'
4 | import { DynamicModuleRoutingModule } from './dynamicModule-routing.module'
5 |
6 | import { importComs } from './comMgr'
7 |
8 | @NgModule({
9 | declarations:[
10 | DynamicComponent,
11 | ...importComs
12 | ],
13 | entryComponents:[
14 | ...importComs
15 | ],
16 | imports:[
17 | DynamicModuleRoutingModule
18 | ]
19 | })
20 | export class DynamicModule{}
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "commonjs",
5 | "moduleResolution": "node",
6 | "sourceMap": true,
7 | "emitDecoratorMetadata": true,
8 | "experimentalDecorators": true,
9 | "removeComments": true,
10 | "noImplicitAny": true,
11 | "suppressImplicitAnyIndexErrors": true,
12 | "typeRoots": [
13 | "node_modules/@types"
14 | ]
15 | },
16 | "exclude": [
17 | "node_modules",
18 | "dist"
19 | ],
20 | "angularCompilerOptions": {
21 | "skipMetadataEmit": true
22 | }
23 | }
--------------------------------------------------------------------------------
/src/app/app.component.scss:
--------------------------------------------------------------------------------
1 | .app{
2 | width: 100%;
3 | padding-top: 50px;
4 | padding-bottom: 50px;
5 | text-align:center;
6 | color:rgba(255,255,255,.8);
7 | background-color: #4a99cc;
8 | background: linear-gradient(
9 | 45deg,
10 | #4a5ccc 30%,
11 | #3fc8b1 100%
12 | );
13 | box-shadow: 0px -3px 10px rgba(0,0,0,0.2) inset;
14 | p{
15 | padding-bottom: 10px;
16 | }
17 | a{
18 | height: 30px;
19 | width: 200px;
20 | line-height: 30px;
21 | display: inline-block;
22 | text-decoration:none;
23 | padding: 5px;
24 | background: rgba(255,255,255,.3);
25 | color:rgba(255,255,255,.8);
26 | margin-bottom: 20px;
27 | }
28 | }
--------------------------------------------------------------------------------
/config/webpack.dev.js:
--------------------------------------------------------------------------------
1 | //开发模式下 webpack 配置
2 | //develop webpack config
3 | var webpack=require('webpack')
4 | var webpackMerge = require('webpack-merge');
5 | var ExtractTextPlugin = require('extract-text-webpack-plugin');
6 | var commonConfig = require('./webpack.common.js');
7 | var helpers = require('./helpers');
8 |
9 | module.exports = webpackMerge(commonConfig, {
10 | devtool: 'cheap-module-eval-source-map',
11 | output: {
12 | path: helpers.root('dist'),
13 | publicPath: '',
14 | filename: '[name].js',
15 | chunkFilename: '[name].chunk.js'
16 | },
17 |
18 | plugins: [
19 | new ExtractTextPlugin('[name].css')
20 | ],
21 |
22 | devServer: {
23 | historyApiFallback: true,
24 | stats: 'minimal',
25 | host:'0.0.0.0',
26 | port: 8111,
27 | contentBase:'src/'
28 | },
29 | });
--------------------------------------------------------------------------------
/src/app/shared/shared.module.ts:
--------------------------------------------------------------------------------
1 | import { CommonModule } from '@angular/common'
2 | import { FormsModule } from '@angular/forms'
3 | import { HttpModule,Http } from '@angular/http'
4 | import { NgModule,ModuleWithProviders } from '@angular/core'
5 |
6 | @NgModule({
7 | imports:[
8 | /* 引入一些此模块需要的其他模块 */
9 | /* import some module that the shared module needs */
10 | ],
11 | declarations:[
12 | /* 声明一些属于shared module的组件或指令,在其他模块导入的时候便会生效 */
13 | /* some shared component or directives */
14 | ],
15 | exports:[
16 | CommonModule,
17 | FormsModule,
18 | HttpModule
19 | /* 导出一些模块 这些模块是经常被使用的模块 其他模块导入shared module时便不用再次导入这些模块 */
20 | /* export some module that always be used */
21 | ]
22 | })
23 | export class SharedModule{
24 | static forRoot():ModuleWithProviders{
25 | return {
26 | ngModule:SharedModule
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule, ApplicationRef } from '@angular/core'
2 | import { BrowserModule } from '@angular/platform-browser'
3 | import {
4 | removeNgStyles,
5 | createNewHosts,
6 | createInputTransfer
7 | } from '@angularclass/hmr'
8 |
9 | import { AppRoutingModule } from './app-routing.module'
10 | import { SharedModule } from './shared/shared.module'
11 | import { CoreModule } from './core/core.module'
12 | import { AppComponent } from './app.component'
13 |
14 | @NgModule({
15 | declarations: [
16 | AppComponent
17 | ],
18 | imports: [
19 | AppRoutingModule,
20 | BrowserModule,
21 | CoreModule.forRoot(),
22 | SharedModule.forRoot()
23 | ],
24 | bootstrap: [
25 | AppComponent
26 | ]
27 | })
28 | // hmr config
29 | export class AppModule {
30 | constructor(public appRef: ApplicationRef) { }
31 | hmrOnInit(store:any) {
32 | }
33 | hmrOnDestroy(store:any) {
34 | let cmpLocation = this.appRef.components.map(cmp => cmp.location.nativeElement)
35 | store.disposeOldHosts = createNewHosts(cmpLocation)
36 | removeNgStyles()
37 | }
38 | hmrAfterDestroy(store:any) {
39 | store.disposeOldHosts()
40 | delete store.disposeOldHosts
41 | }
42 | }
--------------------------------------------------------------------------------
/src/app/dynamicModule/dynamic.component.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Compiler,
3 | Component,
4 | ComponentFactory,
5 | ComponentFactoryResolver,
6 | Injector,
7 | NgModule,
8 | ReflectiveInjector,
9 | ViewChild,
10 | ViewContainerRef
11 | } from '@angular/core'
12 | import { COMPILER_PROVIDERS } from '@angular/compiler'
13 |
14 | import { coms } from './comMgr'
15 |
16 | @Component({
17 | selector: 'dynamic-com',
18 | templateUrl: './dynamicModule.template.html',
19 | styleUrls: [
20 | './dynamicModule.scss'
21 | ]
22 | })
23 | export class DynamicComponent {
24 | @ViewChild('dmroom', { read: ViewContainerRef }) dmRoom: ViewContainerRef;
25 |
26 | private cp: Compiler
27 |
28 | constructor(
29 | private cfr: ComponentFactoryResolver,
30 | private ijt: Injector,
31 | ) {
32 | this.ijt = ReflectiveInjector.resolveAndCreate(COMPILER_PROVIDERS, ijt)
33 | this.cp = this.ijt.get(Compiler)
34 | }
35 |
36 | addComponent() {
37 | let com = this.cfr.resolveComponentFactory(coms['DY1Component'])
38 | this.dmRoom.createComponent(com)
39 | }
40 |
41 | createComponent() {
42 | this.dmRoom.createComponent(this.createModule())
43 | }
44 |
45 | createModule(): ComponentFactory {
46 | @Component({
47 | template: '动态组件'
48 | })
49 | class DyCom { }
50 |
51 | @NgModule({
52 | declarations: [
53 | DyCom
54 | ]
55 | })
56 | class DyModule { }
57 |
58 | return this.cp.compileModuleAndAllComponentsSync(DyModule).componentFactories
59 | .find(comFac => {
60 | return comFac.componentType === DyCom
61 | })
62 | }
63 | }
64 |
65 |
66 |
--------------------------------------------------------------------------------
/config/webpack.prod.js:
--------------------------------------------------------------------------------
1 | //生产环境下 webpack配置文件
2 | //production webpack config
3 | var webpack = require('webpack');
4 | var webpackMerge = require('webpack-merge');
5 | var ExtractTextPlugin = require('extract-text-webpack-plugin');
6 | var commonConfig = require('./webpack.common');
7 | var helpers = require('./helpers');
8 | var ngtools = require('@ngtools/webpack');
9 |
10 | var env=process.env.NODE_ENV;
11 | module.exports = webpackMerge(commonConfig, {
12 | output: {
13 | path: helpers.root('dist'),
14 | publicPath: '',
15 | filename: '[name].[hash].js',
16 | chunkFilename: '[id].[hash].chunk.js'
17 | },
18 | plugins: [
19 | new webpack.NoEmitOnErrorsPlugin(),
20 | new ExtractTextPlugin({
21 | filename: '[name].[hash].css',
22 | disable: false,
23 | allChunks: true
24 | }),
25 | //最小化 (minify)
26 | new webpack.optimize.UglifyJsPlugin({
27 | mangle: true,
28 | screw_ie8: true,
29 | beautify: false,
30 | comments: false,
31 | compress: {
32 | warnings: false,
33 | warnings: true,
34 | drop_console: false,
35 | collapse_vars: true,
36 | reduce_vars: true
37 | }
38 | }),
39 | new webpack.LoaderOptionsPlugin({
40 | options: {
41 | htmlLoader: {
42 | minimize: false
43 | }
44 | }
45 | }),
46 |
47 | //ng2 aot webpack插件配置
48 | //ng2 aot webpack config
49 | new ngtools.AotPlugin({
50 | tsConfigPath: './tsconfig.json',
51 | entryModule: helpers.root('src','app','app.module')+'#AppModule'
52 | }),
53 |
54 | new webpack.DefinePlugin({
55 | 'process.env': {
56 | 'NODE_ENV': JSON.stringify(env)
57 | }
58 | })
59 | ]
60 | });
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular4-seed-starter",
3 | "description": "an angular start design by wuzhouyang",
4 | "version": "1.0.1",
5 | "license": "MIT",
6 | "scripts": {
7 | "server": "superstatic dist/ --port 8112 --host 0.0.0.0 --gzip",
8 | "prestart": "cross-env NODE_ENV=dev",
9 | "start": "webpack-dev-server --progress --inline --hot",
10 | "prebuild": "rimraf dist",
11 | "build": "cross-env NODE_ENV=prod webpack --progress"
12 | },
13 | "dependencies": {
14 | "@angular/animations": "4.0.0",
15 | "@angular/common": "4.0.0",
16 | "@angular/compiler": "4.0.0",
17 | "@angular/compiler-cli": "4.0.0",
18 | "@angular/core": "4.0.0",
19 | "@angular/forms": "4.0.0",
20 | "@angular/http": "4.0.0",
21 | "@angular/platform-browser": "4.0.0",
22 | "@angular/platform-browser-dynamic": "4.0.0",
23 | "@angular/router": "4.0.0",
24 | "core-js": "2.4.1",
25 | "ie-shim": "0.1.0",
26 | "reflect-metadata": "0.1.9",
27 | "rxjs": "5.0.1",
28 | "zone.js": "^0.8.4"
29 | },
30 | "devDependencies": {
31 | "@angular/compiler-cli": "4.0.0",
32 | "@angular/platform-server": "4.0.0",
33 | "@angularclass/hmr": "^1.2.2",
34 | "@angularclass/hmr-loader": "^3.0.2",
35 | "@ngtools/webpack": "1.3.0",
36 | "@types/core-js": "^0.9.34",
37 | "@types/jasmine": "^2.2.34",
38 | "@types/node": "^6.0.40",
39 | "@types/webpack": "^1.12.35",
40 | "angular2-router-loader": "^0.3.5",
41 | "angular2-template-loader": "^0.6.2",
42 | "autoprefixer": "^6.4.1",
43 | "awesome-typescript-loader": "^3.1.2",
44 | "copy-webpack-plugin": "^4.0.1",
45 | "cross-env": "^3.1.3",
46 | "css-loader": "^0.25.0",
47 | "extract-text-webpack-plugin": "2.1.0",
48 | "file-loader": "^0.8.5",
49 | "html-loader": "^0.4.4",
50 | "html-webpack-plugin": "^2.15.0",
51 | "image-webpack-loader": "^2.0.0",
52 | "json-loader": "^0.5.4",
53 | "node-sass": "^3.13.1",
54 | "postcss-loader": "^0.11.1",
55 | "resolve-url-loader": "^1.6.0",
56 | "rimraf": "^2.5.4",
57 | "sass-loader": "^4.0.2",
58 | "style-loader": "^0.13.1",
59 | "superstatic": "^4.0.3",
60 | "to-string-loader": "^1.1.5",
61 | "ts-loader": "^0.8.1",
62 | "typescript": "^2.1.5",
63 | "url-loader": "^0.5.7",
64 | "webpack": "2.2.0",
65 | "webpack-dev-server": "^2.1.0-beta.10",
66 | "webpack-merge": "^0.14.0"
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/config/webpack.common.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 | var HtmlWebpackPlugin = require('html-webpack-plugin');
3 | var ExtractTextPlugin = require('extract-text-webpack-plugin');
4 | var CopyWebpackPlugin = require('copy-webpack-plugin');
5 |
6 | var helpers = require('./helpers');
7 |
8 | //获取命令行下设置的环境变量
9 | var env = process.env.NODE_ENV;
10 | var isProd = env === 'prod';
11 |
12 | module.exports = {
13 | entry: {
14 | 'polyfills': './src/polyfills.ts',
15 | 'vendor': './src/vendor.ts',
16 | 'main': './src/main.ts'
17 | },
18 | //查找依赖文件路径
19 | resolve: {
20 | //指定后缀 查找文件的时候可以省略后缀
21 | //can ignore the ext when find the files
22 | extensions: ['.ts', '.js']
23 | },
24 |
25 | //指定各种loader
26 | //config some loader
27 | module: {
28 | //loader将各种资源文件最终处理为js文件
29 | //loader convert all the resource file to js
30 | loaders: [
31 | {
32 | test: /\.ts$/,
33 | use:
34 | isProd ?
35 | ['@ngtools/webpack'] :
36 | [
37 | '@angularclass/hmr-loader',
38 | 'angular2-template-loader',
39 | 'awesome-typescript-loader',
40 | 'angular2-router-loader'
41 | ]
42 | },
43 | {
44 | test: /\.html$/,
45 | use: ['html-loader']
46 | },
47 | {
48 | test: /\.css$/,
49 | exclude: [
50 | helpers.root('src', 'app')
51 | ],
52 | use: ExtractTextPlugin.extract({
53 | fallback: 'style-loader',
54 | use: [
55 | {
56 | loader: 'css-loader',
57 | options: {
58 | minimize: true
59 | }
60 | }
61 | ]
62 | })
63 | },
64 | {
65 | test: /\.css$/,
66 | include: [
67 | helpers.root('src', 'app')
68 | ],
69 | use: [
70 | { loader: 'to-string-loader' },
71 | { loader: 'css-loader' }
72 | ]
73 | },
74 | {
75 | test: /\.scss$/,
76 | exclude: [
77 | helpers.root('src', 'app')
78 | ],
79 | use: ExtractTextPlugin.extract({
80 | fallback: 'style-loader',
81 | use: [
82 | { loader: 'css-loader' },
83 | { loader: 'sass-loader' }
84 | ]
85 | })
86 | },
87 | {
88 | test: /\.scss$/,
89 | include: [
90 | helpers.root('src', 'app')
91 | ],
92 | use: [
93 | { loader: 'to-string-loader' },
94 | { loader: 'css-loader' },
95 | { loader: 'sass-loader' }
96 | ]
97 | },
98 | {
99 | test: /\.(svg|woff|woff2|ttf|eot)$/,
100 | use: [
101 | {
102 | loader: 'file-loader',
103 | options: {
104 | name: 'assets/iconfonts/[name].[hash].[ext]'
105 | }
106 | }
107 | ]
108 | },
109 | {
110 | test: /\.(png|jpe?g|gif)$/,
111 | use: [
112 | {
113 | loader: 'url-loader',
114 | options: {
115 | limit: 1024,
116 | name: 'assets/imgs/[name].[hash].[ext]'
117 | }
118 | }
119 | ]
120 | }
121 | ]
122 | },
123 |
124 | plugins: [
125 | new webpack.optimize.CommonsChunkPlugin({
126 | name: ['main', 'vendor', 'polyfills']
127 | }),
128 |
129 | !isProd ? new webpack.ContextReplacementPlugin(
130 | /angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/,
131 | __dirname
132 | ) : () => { },
133 |
134 | //直接复制一些静态资源
135 | //copy some static resource
136 | new CopyWebpackPlugin([
137 | {
138 | from: helpers.root('src', 'favicon.ico'),
139 | to: helpers.root('dist', 'favicon.ico')
140 | }
141 | ]),
142 |
143 | new webpack.LoaderOptionsPlugin({
144 | options: {
145 | postcss: [
146 | require('autoprefixer')
147 | ]
148 | }
149 | }),
150 |
151 | new HtmlWebpackPlugin({
152 | template: 'src/index.html'
153 | }),
154 |
155 | //如果想引入jq,使用此代码
156 | //if you want to use jq,use this
157 |
158 | // new webpack.ProvidePlugin({
159 | // $: "jquery",
160 | // jQuery: "jquery",
161 | // "window.jQuery": "jquery"
162 | // })
163 | ]
164 | };
--------------------------------------------------------------------------------