我正在开发一个项目,一切都很顺利,直到我执行了 npm install
。
然后,Webpack 抛出以下错误:
new ForkCheckerPlugin(),
^
TypeError: ForkCheckerPlugin is not a constructor
at makeWebpackConfig (/home/nsanz/Documentos/git/tachology/webpack.make.js:252:9)
at Object.exports.default (/home/nsanz/Documentos/git/tachology/server/config/express.js:86:27)
at Object.<anonymous> (/home/nsanz/Documentos/git/tachology/server/app.js:28:1)
at Module._compile (module.js:570:32)
at loader (/home/nsanz/Documentos/git/tachology/node_modules/babel-register/lib/node.js:144:5)
at Object.require.extensions.(anonymous function) [as .js] (/home/nsanz/Documentos/git/tachology/node_modules/babel-register/lib/node.js:154:7)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.require (module.js:497:17)
at require (internal/module.js:20:19)
at Object.<anonymous> (/home/nsanz/Documentos/git/tachology/server/index.js:12:28)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.runMain (module.js:604:10)
at run (bootstrap_node.js:389:7)
at startup (bootstrap_node.js:149:9)
at bootstrap_node.js:504:3
我的 package.json 看起来像:
{
"name": "tachology",
"version": "0.0.0",
"main": "server/index.js",
"dependencies": {
...
},
"devDependencies": {
"angular-mocks": "~1.6.0",
"autoprefixer": "^7.1.2",
"babel-core": "^6.6.5",
"babel-eslint": "^7.2.3",
"babel-register": "^6.6.5",
"browser-sync": "^2.8.0",
"bs-fullscreen-message": "^1.0.0",
"babel-plugin-transform-class-properties": "^6.6.0",
"babel-plugin-transform-runtime": "^6.6.0",
"babel-preset-es2015": "^6.6.0",
"eslint": "^4.3.0",
"del": "^3.0.0",
"gulp": "^3.9.1",
"gulp-babel": "^6.1.2",
"gulp-env": "^0.4.0",
"gulp-eslint": "^4.0.0",
"gulp-imagemin": "^3.0.1",
"gulp-inject": "^4.0.0",
"gulp-istanbul": "^1.1.1",
"gulp-istanbul-enforcer": "^1.0.3",
"gulp-load-plugins": "^1.0.0-rc.1",
"gulp-mocha": "^4.3.1",
"gulp-node-inspector": "^0.2.0",
"gulp-plumber": "^1.0.1",
"gulp-protractor": "^4.1.0",
"gulp-rev": "^8.0.0",
"gulp-rev-replace": "^0.4.2",
"gulp-sort": "^2.0.0",
"gulp-sourcemaps": "^2.6.0",
"gulp-util": "^3.0.5",
"gulp-watch": "^4.3.5",
"gulp-stylint": "^4.0.0",
"grunt": "^1.0.1",
"grunt-build-control": "^0.7.0",
"isparta": "^4.0.0",
"nodemon": "^1.3.7",
"run-sequence": "^2.1.0",
"lazypipe": "^1.0.1",
"webpack": "^3.4.1",
"webpack-dev-middleware": "^1.5.1",
"webpack-stream": "^3.2.0",
"extract-text-webpack-plugin": "^3.0.0",
"html-webpack-plugin": "^2.16.0",
"html-webpack-harddisk-plugin": "~0.1.0",
"pug-html-loader": "^1.0.8",
"awesome-typescript-loader": "3.2.1",
"ng-annotate-loader": "~0.6.1",
"babel-loader": "^7.1.1",
"css-loader": "^0.28.4",
"file-loader": "^0.11.2",
"imports-loader": "^0.7.1",
"isparta-instrumenter-loader": "^1.0.0",
"isparta-loader": "^2.0.0",
"istanbul-instrumenter-loader": "^2.0.0",
"null-loader": "^0.1.1",
"postcss-loader": "^2.0.6",
"raw-loader": "^0.5.1",
"style-loader": "^0.18.2",
"node-sass": "^4.5.3",
"sass-loader": "^6.0.6",
"karma-webpack": "^2.0.4",
"through2": "^2.0.1",
"open": "~0.0.4",
"istanbul": "1.1.0-alpha.1",
"chai": "^4.1.0",
"sinon": "^2.4.1",
"chai-as-promised": "^7.1.1",
"chai-things": "^0.2.0",
"karma": "~1.7.0",
"karma-firefox-launcher": "^1.0.0",
"karma-script-launcher": "^1.0.0",
"karma-coverage": "^1.0.0",
"karma-chrome-launcher": "^2.0.0",
"karma-phantomjs-launcher": "~1.0.0",
"karma-spec-reporter": "~0.0.20",
"karma-sourcemap-loader": "~0.3.7",
"sinon-chai": "^2.8.0",
"mocha": "^3.0.2",
"jasmine-core": "^2.3.4",
"karma-jasmine": "^1.0.2",
"jasmine-spec-reporter": "^4.1.1",
"phantomjs-prebuilt": "^2.1.4",
"proxyquire": "^1.0.1",
"strip-ansi": "^4.0.0",
"supertest": "^3.0.0"
},
"engines": {
"node": "^6.2.2",
"npm": "^3.9.5"
},
"scripts": {
"test": "gulp test",
"update-webdriver": "node node_modules/protractor/bin/webdriver-manager update",
"start": "node server"
},
"private": true
}
webpacke.make.json 文件:
'use strict';
/*eslint-env node*/
var webpack = require('webpack');
var autoprefixer = require('autoprefixer');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var HtmlWebpackHarddiskPlugin = require('html-webpack-harddisk-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin;
var fs = require('fs');
var path = require('path');
var ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin;
module.exports = function makeWebpackConfig(options) {
/**
* Environment type
* BUILD is for generating minified builds
* TEST is for generating test builds
*/
var BUILD = !!options.BUILD;
var TEST = !!options.TEST;
var E2E = !!options.E2E;
var DEV = !!options.DEV;
/**
* Config
* Reference: http://webpack.github.io/docs/configuration.html
* This is the object where all configuration gets set
*/
var config = {};
/**
* Entry
* Reference: http://webpack.github.io/docs/configuration.html#entry
* Should be an empty object if it's generating a test build
* Karma will set this when it's a test build
*/
if(TEST) {
config.entry = {};
} else {
config.entry = {
app: './client/app/app.js',
polyfills: './client/polyfills.js',
vendor: [
'angular',
'angular-animate',
'angular-aria',
'angular-cookies',
'angular-resource',
'angular-sanitize',
'angular-ui-router',
'lodash'
]
};
}
/**
* Output
* Reference: http://webpack.github.io/docs/configuration.html#output
* Should be an empty object if it's generating a test build
* Karma will handle setting it up for you when it's a test build
*/
if(TEST) {
config.output = {};
} else {
config.output = {
// Absolute output directory
path: BUILD ? path.join(__dirname, '/dist/client/') : path.join(__dirname, '/.tmp/'),
// Output path from the view of the page
// Uses webpack-dev-server in development
publicPath: BUILD || DEV || E2E ? '/' : `http://localhost:${8080}/`,
//publicPath: BUILD ? '/' : 'http://localhost:' + env.port + '/',
// Filename for entry points
// Only adds hash in build mode
filename: BUILD ? '[name].[hash].js' : '[name].bundle.js',
// Filename for non-entry points
// Only adds hash in build mode
chunkFilename: BUILD ? '[name].[hash].js' : '[name].bundle.js'
};
}
if(TEST) {
config.resolve = {
modulesDirectories: [
'node_modules'
],
extensions: ['', '.js', '.ts']
};
}
/**
* Devtool
* Reference: http://webpack.github.io/docs/configuration.html#devtool
* Type of sourcemap to use per build type
*/
if(TEST) {
config.devtool = 'inline-source-map';
} else if(BUILD || DEV) {
config.devtool = 'source-map';
} else {
config.devtool = 'eval';
}
/**
* Loaders
* Reference: http://webpack.github.io/docs/configuration.html#module-loaders
* List: http://webpack.github.io/docs/list-of-loaders.html
* This handles most of the magic responsible for converting modules
*/
config.sassLoader = {
outputStyle: 'compressed',
precision: 10,
sourceComments: false
};
config.babel = {
shouldPrintComment(commentContents) {
// keep `/*@ngInject*/`
return /@ngInject/.test(commentContents);
}
}
// Initialize module
config.module = {
preLoaders: [],
loaders: [{
// JS LOADER
// Reference: https://github.com/babel/babel-loader
// Transpile .js files using babel-loader
// Compiles ES6 and ES7 into ES5 code
test: /\.js$/,
loader: 'babel',
include: [
path.resolve(__dirname, 'client/'),
path.resolve(__dirname, 'node_modules/lodash-es/')
]
}, {
// TS LOADER
// Reference: https://github.com/s-panferov/awesome-typescript-loader
// Transpile .ts files using awesome-typescript-loader
test: /\.ts$/,
loader: 'awesome-typescript-loader',
query: {
tsconfig: path.resolve(__dirname, 'tsconfig.client.json')
},
include: [
path.resolve(__dirname, 'client/')
]
}, {
// ASSET LOADER
// Reference: https://github.com/webpack/file-loader
// Copy png, jpg, jpeg, gif, svg, woff, woff2, ttf, eot files to output
// Rename the file using the asset hash
// Pass along the updated reference to your code
// You can add here any file extension you want to get copied to your output
test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot)([\?]?.*)$/,
loader: 'file'
}, {
// Pug HTML LOADER
// Reference: https://github.com/willyelm/pug-html-loader
// Allow loading Pug throw js
test: /\.(jade|pug)$/,
loaders: ['pug-html']
}, {
// CSS LOADER
// Reference: https://github.com/webpack/css-loader
// Allow loading css through js
//
// Reference: https://github.com/postcss/postcss-loader
// Postprocess your css with PostCSS plugins
test: /\.css$/,
loader: !TEST
// Reference: https://github.com/webpack/extract-text-webpack-plugin
// Extract css files in production builds
//
// Reference: https://github.com/webpack/style-loader
// Use style-loader in development for hot-loading
? ExtractTextPlugin.extract('style', 'css!postcss')
// Reference: https://github.com/webpack/null-loader
// Skip loading css in test mode
: 'null'
}, {
// SASS LOADER
// Reference: https://github.com/jtangelder/sass-loader
test: /\.(scss|sass)$/,
loaders: ['style', 'css', 'sass'],
include: [
path.resolve(__dirname, 'node_modules/bootstrap-sass/assets/stylesheets/*.scss'),
path.resolve(__dirname, 'client/app/app.scss')
]
}]
};
config.module.postLoaders = [{
test: /\.js$/,
loader: 'ng-annotate?single_quotes'
}];
// ISPARTA INSTRUMENTER LOADER
// Reference: https://github.com/ColCh/isparta-instrumenter-loader
// Instrument JS files with Isparta for subsequent code coverage reporting
// Skips node_modules and spec files
if(TEST) {
config.module.preLoaders.push({
//delays coverage til after tests are run, fixing transpiled source coverage error
test: /\.js$/,
exclude: /(node_modules|spec\.js|mock\.js)/,
loader: 'isparta-instrumenter',
query: {
babel: {
// optional: ['runtime', 'es7.classProperties', 'es7.decorators']
}
}
});
}
/**
* PostCSS
* Reference: https://github.com/postcss/autoprefixer-core
* Add vendor prefixes to your css
*/
config.postcss = [
autoprefixer({
browsers: ['last 2 version']
})
];
/**
* Plugins
* Reference: http://webpack.github.io/docs/configuration.html#plugins
* List: http://webpack.github.io/docs/list-of-plugins.html
*/
config.plugins = [
/*
* Plugin: ForkCheckerPlugin
* Description: Do type checking in a separate process, so webpack don't need to wait.
*
* See: https://github.com/s-panferov/awesome-typescript-loader#forkchecker-boolean-defaultfalse
*/
new ForkCheckerPlugin(),
// Reference: https://github.com/webpack/extract-text-webpack-plugin
// Extract css files
// Disabled when in test mode or not in build mode
new ExtractTextPlugin('[name].[hash].css', {
disable: !BUILD || TEST
})
];
if(!TEST) {
config.plugins.push(new CommonsChunkPlugin({
name: 'vendor',
// filename: "vendor.js"
// (Give the chunk a different name)
minChunks: Infinity
// (with more entries, this ensures that no other module
// goes into the vendor chunk)
}));
}
// Skip rendering index.html in test mode
// Reference: https://github.com/ampedandwired/html-webpack-plugin
// Render index.html
let htmlConfig = {
template: 'client/_index.html',
filename: '../client/index.html',
alwaysWriteToDisk: true
}
config.plugins.push(
new HtmlWebpackPlugin(htmlConfig),
new HtmlWebpackHarddiskPlugin()
);
// Add build specific plugins
if(BUILD) {
config.plugins.push(
// Reference: http://webpack.github.io/docs/list-of-plugins.html#noerrorsplugin
// Only emit files when there are no errors
new webpack.NoErrorsPlugin(),
// Reference: http://webpack.github.io/docs/list-of-plugins.html#dedupeplugin
// Dedupe modules in the output
new webpack.optimize.DedupePlugin(),
// Reference: http://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin
// Minify all javascript, switch loaders to minimizing mode
new webpack.optimize.UglifyJsPlugin({
mangle: false,
output: {
comments: false
},
compress: {
warnings: false
}
}),
// Reference: https://webpack.github.io/docs/list-of-plugins.html#defineplugin
// Define free global variables
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
})
);
}
if(DEV) {
config.plugins.push(
// Reference: https://webpack.github.io/docs/list-of-plugins.html#defineplugin
// Define free global variables
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"development"'
}
})
);
}
config.cache = DEV;
if(TEST) {
config.stats = {
colors: true,
reasons: true
};
config.debug = false;
}
/**
* Dev server configuration
* Reference: http://webpack.github.io/docs/configuration.html#devserver
* Reference: http://webpack.github.io/docs/webpack-dev-server.html
*/
config.devServer = {
contentBase: './client/',
stats: {
modules: false,
cached: false,
colors: true,
chunk: false
}
};
config.node = {
global: 'window',
process: true,
crypto: 'empty',
clearImmediate: false,
setImmediate: false
};
return config;
};
我尝试将 Webpack 降级到版本 1.15.0,删除 node_modules
文件夹并重新安装,但仍然遇到相同的错误。
出了什么问题?
更新:
以防万一它有帮助,当我执行npm install
时,Webpack模块显示如下UNMET PEER DEPENDENCY webpack@3.4.1
。
将 Awesome-typescript-loader 降级到 2.2.4 时出现以下错误:
WebpackOptionsValidationError(webpackOptionsValidationErrors);
^
WebpackOptionsValidationError: Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration has an unknown property 'postcss'. These properties are valid:
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry, externals?, loader?, module?, name?, node?, output?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, stats?, target?, watch?, watchOptions? }
For typos: please correct them.
For loader options: webpack 2 no longer allows custom properties in configuration.
Loaders should be updated to allow passing options via loader options in module.rules.
Until loaders are updated one can use the LoaderOptionsPlugin to pass these options to the loader:
plugins: [
new webpack.LoaderOptionsPlugin({
// test: /\.xxx$/, // may apply this only for some modules
options: {
postcss: ...
}
})
]
- configuration.module has an unknown property 'postLoaders'. These properties are valid:
object { exprContextCritical?, exprContextRecursive?, exprContextRegExp?, exprContextRequest?, loaders?, noParse?, rules?, unknownContextCritical?, unknownContextRecursive?, unknownContextRegExp?, unknownContextRequest?, unsafeCache?, wrappedContextCritical?, wrappedContextRecursive?, wrappedContextRegExp?, strictExportPresence?, strictThisContextOnImports? }
Options affecting the normal modules (`NormalModuleFactory`).
- configuration.node should be one of these:
false | object { Buffer?, __dirname?, __filename?, console?, global?, process?, ... }
Include polyfills or mocks for various node stuff.
Details:
* configuration.node should be false
* configuration.node.global should be a boolean.
更新2:
降级 webpack@2.1.0-beta.22 似乎解决了我的问题。但现在,我收到另一个错误:
/home/nsanz/Documentos/git/tachology/node_modules/extract-text-webpack-plugin/node_modules/async/dist/async.js:1003
iteratee(coll[index], index, onlyOnce(iteratorCallback));
^
TypeError: chunk.sortModules is not a function
更新3:
安装 extract-text-webpack-plugin@2.1.2 后,我收到此新错误:
/home/nsanz/Documentos/git/tachology/node_modules/extract-text-webpack-plugin/index.js:187
throw new Error("Breaking change: extract now only takes a single argument. Either an options " +
^
Error: Breaking change: extract now only takes a single argument. Either an options object *or* the loader(s).
Example: if your old code looked like this:
ExtractTextPlugin.extract('style-loader', 'css-loader')
You would change it to:
ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader' })
The available options are:
use: string | object | loader[]
fallback: string | object | loader[]
publicPath: string
更新4:
修复另一个 ExtractTextPlugin 错误后,我收到一个新错误(我通过不同的 pug 文件找到了这个错误):
ERROR in ./client/app/main/main.pug
Module parse failed: /home/nsanz/Documentos/git/tachology/node_modules/pug-html-loader/lib/index.js!/home/nsanz/Documentos/git/tachology/client/app/main/main.pug Unexpected token (1:0)
You may need an appropriate loader to handle this file type.
| <div class="uk-section uk-section-default main"><div class="uk-container" ng-show="$ctrl.Auth.hasRoleSync('driver')"><div class="uk-flex"><div class="uk-width-1-3"><div class="test-upload uk-placeholder uk-text-center"><span uk-icon="icon: cloud-upload; ratio: 3"></span><br/><span class="uk-text-middle uk-margin-small-left uk-margin-small-right">Arrastra los ficheros o</span><div class="uk-form-custom"><input type="file" multiple="multiple" enctype="multipart/form-data" ng-model="$ctrl.upload"/><span class="uk-link">pulsa aquí</span></div></div><progress class="uk-progress" id="progressbar" value="0" max="100" hidden="hidden"></progress></div><div class="uk-width-2-3 uk-margin-left"><table class="uk-table uk-table-hover uk-table-striped uk-table-small uk-table-justify" id="files"><thead><tr><th class="uk-table-shrink">#</th><th class="uk-table-expand">Nombre del Fichero</th><th class="uk-table-expand"><form class="uk-search uk-search-default uk-width-1-1"><span class="uk-search-icon"></span><input class="uk-search-input" type="search" placeholder="Buscar..." ng-model="search.filename"/></form></th></tr></thead><tbody><tr class="uk-text-center empty-msg" ng-hide="$ctrl.fileList.length !== 0"><td colspan="3">No se encuentra ningún fichero, <a href="signup">subir uno nuevo.</a></td></tr><tr ng-repeat="file in $ctrl.fileList | filter:search"><td>{{$index + 1}}</td><td class="uk-table-link"><a class="uk-link-reset" ng-click="$ctrl.parseFile(file)">{{file.filename}}</a></td><td class="uk-text-right"><i class="uk-icon-link download" uk-icon="icon: cloud-download" ng-click="$ctrl.downloadFile(file)"></i><i class="uk-icon-link uk-margin-left trash" uk-icon="icon: trash" ng-click="$ctrl.deleteFile(file)"></i></td></tr></tbody></table></div></div></div><div class="uk-container" ng-hide="$ctrl.Auth.hasRoleSync('driver')"><div class="uk-flex uk-flex-around uk-flex-stretch"><div class="uk-width-1-3 uk-card uk-card-default uk-card-hover uk-card-body main-button" ng-click="$ctrl.go('/conductores')"><div class="uk-text-center"><span uk-icon="icon: users; ratio: 4"></span><h3 class="uk-card-title">CONDUCTORES</h3></div></div><div class="uk-width-1-3 uk-card uk-card-default uk-card-hover uk-card-body uk-margin-left main-button" ng-click="$ctrl.go('/vehiculos')"><div class="uk-text-center"><span class="fa fa-car"></span><h3 class="uk-card-title">VEHÍCULOS</h3></div></div><div class="uk-width-1-3 uk-card uk-card-default uk-card-hover uk-card-body uk-margin-left main-button" ng-click="$ctrl.go('/informes')"><div class="uk-text-center"><span uk-icon="icon: list; ratio: 4"></span><h3 class="uk-card-title">INFORMES</h3></div></div></div></div></div>
@ ./client/app/main/main.component.js 140:12-33
@ ./client/app/app.js
最佳答案
在您的 devDependency 中,尝试降级此:
awesome-typescript-loader": "3.2.1"
对此:
awesome-typescript-loader": "2.2.4"
如果还是不行,我们会寻找其他解决方案。
<小时/>编辑
在最后一个问题更新后,这是我的建议。 删除webpack.make.json
中的下一行:
config.plugins = [
/*...*/
new ForkCheckerPlugin(), // <-- Delete this line
这样做的原因是,fork 似乎是 Webpack >= 3.0.0 内置的
<小时/>编辑2
看起来 Webpack 3.4.1 给你带来了麻烦,因为你依赖于一些旧的依赖项。执行以下操作:
npm uninstall webpack --save-dev
然后:
npm install webpack@2.1.0-beta.22 --save-dev
希望这现在能起作用!
如果仍然不起作用,请尝试重新合并 new ForkCheckerPlugin()
语句(这次使用 webpack 2.1.0)
编辑3
它现在似乎可以与 webpack 2.1.0-beta.22
一起使用,但您遇到了另一个错误。
发生此错误的原因是 extract-text-webpack-plugin
与 webpack
的主要版本不同(3.x.x 与 2.x.x)。这样做:
npm uninstall --save-dev extract-text-webpack-plugin
然后这个:
npm install --save-dev extract-text-webpack-plugin@2.1.2
<小时/>
编辑4
这个新错误更容易解决。它在您的错误日志中进行了解释。在您的 webpack.make.js
中更改以下行:
ExtractTextPlugin.extract('style', 'css!postcss')
致:
ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader' })
<小时/>
编辑 5
事情变得有趣了。我建议更改此设置(在 webpack.make.js
内部):
}, {
// Pug HTML LOADER
// Reference: https://github.com/willyelm/pug-html-loader
// Allow loading Pug throw js
test: /\.(jade|pug)$/,
loaders: ['pug-html']
}, {
对此:
}, {
// Pug HTML LOADER
// Reference: https://github.com/willyelm/pug-html-loader
// Allow loading Pug throw js
test: /\.(jade|pug)$/,
loaders: ['pug-html-loader']
}, {
关于node.js - 如何防止 npm 安装后出现 Webpack 错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45491133/