Webpack Html-loader不会在包

时间:2017-09-30 13:34:50

标签: angular typescript webpack webpack-html-loader

我无法使用Angular(4.4.4)和Webpack(3.6.0)创建初学者项目。我的配置在我的template中使用了AOT构建和component声明,但是只要我添加一个html模板(并将template替换为templateUrl),Webpack就会进入无限循环并卡在95% emtitting。我使用html-loader V0.5.1进行模板加载

webpack.common.js

module.exports = {
    entry: {
        app: './src/main.ts',
        vendor: getVendorPackages()
    },
    output: {
        path: __dirname + '/dist',
        filename: "app.bundle.js"
    },
    module: {
        loaders: [
            {
                test: /\.ts$/,
                loaders: ['awesome-typescript-loader', 'angular2-template-loader']
            },
            {
                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']
    }
};

app.component.ts

import {Component} from '@angular/core';

@Component({
    selector: 'hn-root',
    // template: `<h1>Hello world</h1>`
    templateUrl: 'app.html',
    // styleUrls: ['./app.scss']
})
export class AppComponent {
}

app.html

<h1>Hello big world</h1>

的package.json

{
  "name": "angular-webpack-starter",
  "version": "0.1.0",
  "scripts": {
    "build": "webpack --config webpack.dev.js",
    "serve": "webpack-dev-server --config webpack.dev.js",
    "build --prod": "webpack -p --config webpack.prod.js --progress"
  },
  "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",
    "html-loader": "0.5.1",
    "html-webpack-plugin": "2.30.1",
    "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"
  }
}

我显然做错了什么,但我无法弄清楚那是什么..

我已尝试

  • templateUrl更改为&#39; ./ app.html&#39;

  • app.html更改为app.component.html(角度惯例)

  • loaders:[angular2-template-loader]更改为loaders:[angular2-template-loader?keepUrl=true]

我还检查了大多数角度启动器(包括angular-cli)的webpack.config.js,他们使用的是raw-loader而不是html-loader。让我想知道,可以html-loaderAOT compilation结合使用,因为它会创建内联HTML吗?

1 个答案:

答案 0 :(得分:0)

要回答我自己的问题,我在webpack.common.js中犯了一个错误。我使用了密钥loaders,我应该使用密钥rules

所以新代码将是:

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']
    }
};

或更具体:

 module: {
    rules: [
        {
            test: /\.html$/,
            loader: 'html-loader'
        }
    ]
},

您可能还会注意到/\.ts$/规则已消失。这是因为AOT编译使用它自己的打字稿编译器而webpack-merge不会覆盖规则。因此,我不得不将编译移动到开发配置:

<强> webpack.dev.ts

module.exports = merge(common, {
    module: {
      rules: [
          {
              test: /\.ts$/, //Prod uses AOT for .ts and webpack does not override the rules, so they need to be separated
              loaders: ['awesome-typescript-loader', 'angular2-template-loader']
          },
      ]
    },
    plugins: [
        new BundleAnalyzerPlugin({ //Make bundle sizes visible
            analyzerMode: 'static',
            openAnalyzer: false
        }),
        new webpack.DefinePlugin({ //Set the node env so that the project knows what to enable or disable
            'process.env': {
                'NODE_ENV': JSON.stringify('development')
            }
        })
    ],
    devtool: 'eval-source-map',
});

为了扩展我的答案并制作一个有效的例子(使用AOT编译)我还必须向tsconfig.json添加一些数据(参见AOT documentation):

 "files": [
    "src/app/app.module.ts",
    "src/main.ts"
  ],

  "angularCompilerOptions": {
    "genDir": "aot",
    "skipMetadataEmit" : true
  }

结合使用以下 tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "module": "es2015",
    "moduleResolution": "node",
    "noImplicitAny": true,
    "suppressImplicitAnyIndexErrors": true,
    "removeComments": false,
    "sourceMap": true,
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2017",
      "dom"
    ]
  },

  "files": [
    "src/app/app.module.ts",
    "src/main.ts"
  ],

  "angularCompilerOptions": {
    "genDir": "aot",
    "skipMetadataEmit" : true
  }
}