Webpack/Karma/awesome-typescript-загрузчик не будет игнорировать файлы
Я использую Webpack 2.x для компиляции моего приложения Angular 2. Для производственного кода я использую комбинацию ngc
а также @ngtools/webpack
AotPlugin для компиляции. Для тестирования я использую awesome-typescript-loader
, Производственная сборка моего кода работает просто отлично. Тем не менее, когда я делаю npm test
что-то очень странное происходит... awesome-typescript-loader
жалуется, что не смог скомпилировать код, но Карма все равно проходит тесты и все они проходят.
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)
Это хитрый трюк, но я бы предпочел пропустить попытку синтаксического анализа этого файла, тем более что этот файл генерируется.
Моей первой мыслью было игнорировать каталог, в котором создается файл. Он создается в папке с именем ngfactory
, Вот правило, которое я добавил следующее правило в мой webpack.config.js
:
{
test: /\.ts$/,
loaders: ['awesome-typescript-loader', 'angular2-template-loader'],
exclude: [/(node_modules|bootstrap|prebuild|ngfactory)/]
}
Но awesome-typescript-loader
продолжает пытаться разобрать этот файл, несмотря на exclude
, Затем я подумал, что это может быть Карма, поэтому я добавил правило исключения в свой 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'
],
...
...
Когда я удалил папки с артефактами (prebuild
а также ngfactory
) Я понял, что файл начальной загрузки (который находится в каталоге с именем bootstrap
) был проанализирован, и этот файл пытался импортировать app.module.ngfactory.ts
я добавил bootstrap
к различным exclude
свойства (включая мой tsconfig.json
). Тем не менее, ничто не остановило проблему. Если кто-нибудь видел что-то подобное, я хотел бы знать, как вы справились с этим.
Вот мой полный 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)
Вот мой 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"
}
}
Для хорошей меры, вот мой 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)
}
1 ответ
Хотя я не смог остановиться awesome-typescript-loader
от компиляции артефактов я смог заставить его перестать работать, когда бы он ни делал. Загрузчик имеет логическую настройку под названием transpileOnly
, Установка этого в true
не позволяет загрузчику выполнять проверку типов. Я добавил это в свой tsconfig.json
в awesomeTypescriptLoaderOptions
раздел.
Это не идеально, но я в порядке (пока) с awesome-typescript-loader
не обеспечивает проверку типов на стороне тестирования... я думаю... до тех пор, пока ngc
действительно применяет его в производственном коде.
Вот мой 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"
}
}