简体   繁体   English

Webpack / Karma / awesome-typescript-loader不会忽略文件

[英]Webpack/Karma/awesome-typescript-loader Won't Ignore Files

I use Webpack 2.x to compile my Angular 2 App. 我使用Webpack 2.x编译Angular 2 App。 For production code I use a combination of ngc and @ngtools/webpack 's AotPlugin for compilation. 对于生产代码,我结合使用ngc@ngtools/webpack的AotPlugin进行编译。 For testing I use awesome-typescript-loader . 为了测试,我使用awesome-typescript-loader The production build of my code works just fine. 我的代码的生产版本工作正常。 However, when I do an npm test something very strange happens... awesome-typescript-loader complains that it failed to compile the code, but Karma runs through the tests anyway and they all pass. 但是,当我执行npm test时,发生了非常奇怪的事情…… awesome-typescript-loader抱怨它未能编译代码,但是Karma仍然通过了测试,并且都通过了测试。

bash-3.2$ npm test
> btc2017@1.0.0 test /Users/tomb/Projects/brandontom.com/wp-content/themes/btc2017
> NODE_ENV=test node ./node_modules/.bin/karma start --single-run=true

webpack: wait until bundle finished:

[at-loader] Using typescript@2.2.1 from typescript and "tsconfig.json" from /Users/tomb/Projects/brandontom.com/wp-content/themes/b
tc2017/tsconfig.json.
[at-loader] Checking started in a separate process...
[at-loader] Ok, 1.054 sec.
ERROR in ./ngfactory/src/app/app.module.ngfactory.ts
Module parse failed: /Users/tomb/Projects/brandontom.com/wp-content/themes/btc2017/ngfactory/src/app/app.module.ngfactory.ts Unexpe
cted token (65:56)
You may need an appropriate loader to handle this file type.
| import * as import55 from '@angular/router/src/router_config_loader';
| import * as import56 from '@angular/router/src/router_state';
| class AppModuleInjector extends import0.NgModuleInjector<import1.AppModule> {
|   _CommonModule_0:import2.CommonModule;
|   _ApplicationModule_1:import3.ApplicationModule;
 @ ./bootstrap/main.aot.ts 1:0-78
webpack: Failed to compile.
Chrome 56.0.2924 (Mac OS X 10.12.3): Executed 4 of 4 SUCCESS (1.41 secs / 0.758 secs)

That's a neat trick, but I'd rather skip trying to parse that file in the first place, especially since that file is generated. 这是一个巧妙的技巧,但是我宁愿跳过尝试首先解析该文件的过程,特别是因为该文件已生成。

My first thought was to ignore the directory that file gets generated in. It gets constructed in a folder called ngfactory . 我的第一个想法是忽略生成文件的目录。它被构建在名为ngfactory的文件夹中。 Here's the rule that I've added the following rule to my webpack.config.js : 这是我将以下规则添加到webpack.config.js规则:

{
  test: /\.ts$/,
  loaders: ['awesome-typescript-loader', 'angular2-template-loader'],
  exclude: [/(node_modules|bootstrap|prebuild|ngfactory)/]
}

But awesome-typescript-loader keeps trying to parse this file despite the exclude . 但是,尽管exclude但是awesome-typescript-loader仍然尝试解析此文件。 Next I thought it might be Karma that was pulling this in so I added an exclude rule to my karma.conf.js . 接下来,我认为可能是Karma导致了此问题,因此我在我的karma.conf.js添加了排除规则。

module.exports = function (config) {
  var _config = {
    basePath: '',
    frameworks: ['jasmine'],
    files: [
      { pattern: './karma-shim.js', watched: false }
    ],
    exclude: [
      'bootstrap',
      'dist',
      'ngfactory',     // <--- here's where that file lives
      'node_modules',
      'prebuild'
    ],
...
...

When I removed the artifact folders ( prebuild and ngfactory ) I realized that the bootstrap file (which lives in a directory called bootstrap ) was being parsed and that file was trying to import app.module.ngfactory.ts I added bootstrap to the various exclude properties (including my tsconfig.json ). 当我删除工件文件夹( prebuildngfactory )时,我意识到引导文件(位于名为bootstrap的目录中)正在解析,并且该文件正尝试导入app.module.ngfactory.ts我将bootstrap添加到了各种exclude属性(包括我的tsconfig.json )。 Still, nothing stopped the issue from arising. 但是,没有任何事情可以阻止该问题的产生。 If anyone has seen anything like this, I'd love to know how you got around this. 如果有人看到过这样的内容,我很想知道您是如何做到的。

Here's my full webpack.config.js : 这是我完整的webpack.config.js

var neat = require('node-neat')
var path = require('path')
var webpack = require('webpack')
var AotPlugin = require('@ngtools/webpack').AotPlugin

var sassPaths = neat.includePaths.map(function (path) {
  return 'includePaths[]=' + path
}).join('&')

module.exports = (function (nodeEnv) {
  var config = {
    entry: {
      globals: [ 'core-js/client/shim.min', 'reflect-metadata', 'zone.js' ],
      main: path.resolve(__dirname, 'bootstrap') + '/main.aot.ts'
    },
    devServer: {
      inline: true
    },
    module: {
      rules: [
        { test: /\.html$/, loader: 'raw-loader' },
        { test: /\.scss$/, loader: 'raw-loader!css-loader!sass-loader?' + sassPaths, exclude: /node_modules/ }
      ]
    },
    output: {
      filename: '[name].js',
      path: path.resolve(__dirname, 'dist')
    },
    resolve: {
      extensions: ['.js', '.ts']
    },
    plugins: [
      new webpack.ContextReplacementPlugin(
        /angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/,
        __dirname
      ),
      new webpack.DefinePlugin({
        process: { env: { NODE_ENV: JSON.stringify(nodeEnv) } }
      })
    ]
  }
  if (nodeEnv !== 'test') {
    config.module.rules.push({
      test: /\.ts$/,
      loader: '@ngtools/webpack'
    })
    config.plugins.push(new AotPlugin({
      tsConfigPath: './tsconfig.json'
    }))
    config.plugins.push(new webpack.optimize.UglifyJsPlugin({
      mangle: { screw_ie8: true, keep_fnames: true },
      compress: { screw_ie8: true, warnings: false },
      comments: false
    }))
  } else {
    config.module.rules.push({
      test: /\.ts$/,
      loaders: ['awesome-typescript-loader', 'angular2-template-loader'],
      exclude: [/(node_modules|bootstrap|prebuild|ngfactory)/]
    })
  }
  return config
})(process.env.NODE_ENV)

Here's my tsconfig.json : 这是我的tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "module": "es2015",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "sourceMap": true,
    "noEmitHelpers": false,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "outDir": "./prebuild",
    "lib": [
      "es2015",
      "dom"
    ],
    "types": [
      "jasmine",
      "node"
    ]
  },
  "compileOnSave": false,
  "buildOnSave": false,
  "awesomeTypescriptLoaderOptions": {
    "forkChecker": true,
    "useWebpackText": true
  },
  "angularCompilerOptions": {
    "genDir": "./ngfactory",
    "entryModule": "src/app/app.module#AppModule"
  }
}

For good measure, here's my karma.conf.js as well: 从好的方面来说,这也是我的karma.conf.js

var webpackConfig = require('./webpack.config')

module.exports = function (config) {
  var _config = {
    basePath: '',
    frameworks: ['jasmine'],
    files: [
      { pattern: './karma-shim.js', watched: false }
    ],
    exclude: [
      'bootstrap',
      'dist',
      'ngfactory',
      'node_modules',
      'prebuild'
    ],
    preprocessors: {
      './karma-shim.js': ['webpack']
    },
    webpack: webpackConfig,
    webpackMiddleware: {
      stats: 'errors-only'
    },
    webpackServer: {
      noInfo: true
    },
    progress: ['progress'],
    port: 9876,
    color: true,
    logLevel: config.LOG_ERROR,
    browsers: ['Chrome']
  }
  config.set(_config)
}

Although I wasn't able to stop awesome-typescript-loader from compiling artifacts, I was able to get it to stop failing whenever it did. 尽管我无法阻止awesome-typescript-loader编译工件,但awesome-typescript-loader ,我都能使它停止失败。 The loader has a boolean setting called transpileOnly . 加载程序具有一个称为transpileOnly的布尔设置。 Setting this to true prevents the loader from doing type checking. 将其设置为true可以防止加载程序进行类型检查。 I added it to my tsconfig.json in the awesomeTypescriptLoaderOptions section. 我在awesomeTypescriptLoaderOptions部分tsconfig.json其添加到了tsconfig.json中。

This isn't ideal, but I'm okay (for now) with awesome-typescript-loader not enforcing type checking on the testing side... I guess... So long as ngc does enforce it on production code. 这不是理想的选择,但是我现在还可以使用awesome-typescript-loader而不在测试端强制执行类型检查...我想...只要ngc确实在生产代码上强制执行它。

Here's my tsconfig.json 这是我的tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "module": "es2015",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "sourceMap": true,
    "noEmitHelpers": false,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "outDir": "./prebuild",
    "lib": [
      "es2015",
      "dom"
    ],
    "types": [
      "jasmine",
      "node"
    ]
  },
  "compileOnSave": false,
  "buildOnSave": false,
  "awesomeTypescriptLoaderOptions": {
    "forkChecker": true,
    "useWebpackText": true,
    "transpileOnly": true
  },
  "angularCompilerOptions": {
    "genDir": "./ngfactory",
    "entryModule": "src/app/app.module#AppModule"
  }
}

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

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