我正在从webpack 3升级到4.html-webpack-plugin在这里遇到`enter code
ERROR in Must have a source file to refactor.
Child html-webpack-plugin for "index.html":
1 asset
Entrypoint html-webpack-plugin for "index.html" = ./index.html
[./node_modules/html-webpack-plugin/lib/loader.js!./pre-index.html] 1.91 KiB {html-webpack-plugin for "index.html"} [built]
Child html-webpack-plugin for "login.html":
1 asset
Entrypoint html-webpack-plugin for "login.html" = ./login.html
[./node_modules/html-webpack-plugin/lib/loader.js!./pre-login.html] 5.31 KiB {html-webpack-plugin for "login.html"} [built]
? ?wdm?: Failed to compile.
它似乎正在尝试将入口点设置为自身?
webpack配置文件很大,但这里是相关部分
new HtmlWebpackPlugin({
template: './pre-index.html',
filename: outputIndexHtmlFile,
hash: false,
inject: true,
compile: true,
favicon: false,
minify: false,
cache: true,
showErrors: true,
chunks: 'all',
excludeChunks: ['scripts-login', 'ng1'],
title: 'Webpack App',
xhtml: true,
chunksSortMode: function sort(left, right) {
const leftIndex = entryPoints.indexOf(left.names[0])
const rightindex = entryPoints.indexOf(right.names[0])
if (leftIndex > rightindex) {
return 1
} else if (leftIndex < rightindex) {
return -1
} else {
return 0
}
}
}),
new HtmlWebpackPlugin({
template: './pre-login.html',
filename: outputLoginHtmlFile,
hash: false,
inject: true,
compile: true,
favicon: false,
minify: false,
cache: true,
showErrors: true,
chunks: ['inline', 'ng1', 'scripts-login'],
excludeChunks: [],
title: 'Webpack App',
xhtml: true,
chunksSortMode: function sort(left, right) {
const leftIndex = entryPointsLogin.indexOf(left.names[0])
const rightindex = entryPointsLogin.indexOf(right.names[0])
if (leftIndex > rightindex) {
return 1
} else if (leftIndex < rightindex) {
return -1
} else {
return 0
}
}
}),
module.exports = function(env) {
return {
mode:'development',
resolve: {
extensions: ['.ts', '.js'],
modules: ['./node_modules', './node_modules']
},
resolveLoader: {
modules: ['./node_modules', './node_modules']
},
entry: {
main: ['./main.js', './ng2/main.ts'],
polyfills: ['./ng2/polyfills.ts'],
scripts: 'script-loader!./concat/concat.js',
styles: ['./ng2/styles.scss'],
ng1: './ng2/ng1.config.ts',
'scripts-login': loginDependencies
},
output: {
path: path.join(process.cwd(), 'dist'),
filename: '[name].bundle.js',
chunkFilename: '[id].chunk.js'
},
答案 0 :(得分:0)
我解决了这个问题。这是我更新的webpack配置文件。我没有确定问题的具体解决方案。此外,我将所有软件包更新到最新版本。我希望我能提供更好的答案。
const fs = require('fs')
const path = require('path')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const ProgressPlugin = require('webpack/lib/ProgressPlugin')
const CircularDependencyPlugin = require('circular-dependency-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const rxPaths = require('rxjs/_esm5/path-mapping')
const autoprefixer = require('autoprefixer')
const postcssUrl = require('postcss-url')
const postcssImports = require('postcss-import')
const loginDependencies = require('./login/scripts').map(dep => `script-loader!${dep}`)
const babelFiles = [path.join(process.cwd(), 'components/'), path.join(process.cwd(), 'services/'), path.join(process.cwd(), 'models/'), path.join(process.cwd(), 'ng1/'), path.join(process.cwd(), 'utils/'), path.join(process.cwd(), 'main.js')]
const { NoEmitOnErrorsPlugin, EnvironmentPlugin, HashedModuleIdsPlugin } = require('webpack')
const { BaseHrefWebpackPlugin, SuppressExtractedTextChunksWebpackPlugin, CleanCssWebpackPlugin, BundleBudgetPlugin, PostcssCliResources } = require('@angular/cli/plugins/webpack')
const { ModuleConcatenationPlugin } = require('webpack').optimize
// const { LicenseWebpackPlugin } = require('license-webpack-plugin')
const { PurifyPlugin } = require('@angular-devkit/build-optimizer')
const { AngularCompilerPlugin } = require('@ngtools/webpack')
const entryPointsLogin = ['inline', 'ng1', 'scripts-login']
const nodeModules = path.join(process.cwd(), 'node_modules')
const realNodeModules = fs.realpathSync(nodeModules)
const genDirNodeModules = path.join(process.cwd(), 'src', '$$_gendir', 'node_modules')
const entryPoints = ['inline', 'polyfills', 'sw-register', 'styles', 'vendor', 'main']
const hashFormat = {
chunk: '.[chunkhash:20]',
extract: '.[contenthash:20]',
file: '.[hash:20]',
script: '.[hash:20]'
}
const baseHref = ''
const deployUrl = ''
const projectRoot = process.cwd()
const maximumInlineSize = 10
const postcssPlugins = function(loader) {
return [
postcssImports({
resolve: (url, context) => {
return new Promise((resolve, reject) => {
let hadTilde = false
if (url && url.startsWith('~')) {
url = url.substr(1)
hadTilde = true
}
loader.resolve(context, (hadTilde ? '' : './') + url, (err, result) => {
if (err) {
if (hadTilde) {
reject(err)
return
}
loader.resolve(context, url, (err, result) => {
if (err) {
reject(err)
} else {
resolve(result)
}
})
} else {
resolve(result)
}
})
})
},
load: filename => {
return new Promise((resolve, reject) => {
loader.fs.readFile(filename, (err, data) => {
if (err) {
reject(err)
return
}
const content = data.toString()
resolve(content)
})
})
}
}),
postcssUrl({
filter: ({ url }) => url.startsWith('~'),
url: ({ url }) => {
const fullPath = path.join(projectRoot, 'node_modules', url.substr(1))
return path.relative(loader.context, fullPath).replace(/\\/g, '/')
}
}),
postcssUrl([
{
// Only convert root relative URLs, which CSS-Loader won't process into require().
filter: ({ url }) => url.startsWith('/') && !url.startsWith('//'),
url: ({ url }) => {
if (deployUrl.match(/:\/\//) || deployUrl.startsWith('/')) {
// If deployUrl is absolute or root relative, ignore baseHref & use deployUrl as is.
return `${deployUrl.replace(/\/$/, '')}${url}`
} else if (baseHref.match(/:\/\//)) {
// If baseHref contains a scheme, include it as is.
return baseHref.replace(/\/$/, '') + `/${deployUrl}/${url}`.replace(/\/\/+/g, '/')
} else {
// Join together base-href, deploy-url and the original URL.
// Also dedupe multiple slashes into single ones.
return `/${baseHref}/${deployUrl}/${url}`.replace(/\/\/+/g, '/')
}
}
},
{
// TODO: inline .cur if not supporting IE (use browserslist to check)
filter: asset => {
return maximumInlineSize > 0 && !asset.hash && !asset.absolutePath.endsWith('.cur')
},
url: 'inline',
// NOTE: maxSize is in KB
maxSize: maximumInlineSize,
fallback: 'rebase'
},
{
url: 'rebase'
}
]),
PostcssCliResources({
deployUrl: loader.loaders[loader.loaderIndex].options.ident == 'extracted' ? '' : deployUrl,
loader,
filename: `[name]${hashFormat.file}.[ext]`
}),
autoprefixer({
grid: true
})
]
}
module.exports = {
mode: 'development',
resolve: {
extensions: ['.ts', '.js'],
symlinks: true,
modules: ['./node_modules'],
// alias: rxPaths(),
mainFields: ['browser', 'module', 'main']
},
resolveLoader: {
modules: ['./node_modules']
// alias: rxPaths()
},
entry: {
main: ['./main.js', './ng2/main.ts'],
polyfills: ['./ng2/polyfills.ts'],
scripts: 'script-loader!./concat/concat.js',
styles: ['./ng2/styles.scss'],
ng1: './ng2/ng1.config.ts',
'scripts-login': loginDependencies
},
output: {
path: path.join(process.cwd(), 'dist'),
filename: '[name].bundle.js',
chunkFilename: '[id].chunk.js'
// crossOriginLoading: false
},
module: {
rules: [
{
enforce: 'pre',
test: /\.js$/,
loader: 'source-map-loader',
exclude: [/\/node_modules\//]
},
{
test: /\.html$/,
loader: 'raw-loader'
},
{
test: /\.(eot|svg|cur)$/,
loader: 'file-loader',
options: {
name: '[name].[hash:20].[ext]',
limit: 10000
}
},
{
test: /\.(jpg|png|webp|gif|otf|ttf|woff|woff2|ani)$/,
loader: 'url-loader',
options: {
name: '[name].[hash:20].[ext]',
limit: 10000
}
},
// {
// test: /\.js$/,
// use: [
// {
// loader: 'cache-loader',
// options: {
// cacheDirectory: 'C:\\Workspace\\TEMP\\angular-cli-webpack4-sample\\node_modules\\@angular-devkit\\build-optimizer\\src\\.cache'
// }
// },
// {
// loader: '@angular-devkit/build-optimizer/webpack-loader',
// options: {
// sourceMap: false
// }
// }
// ]
// },
{
exclude: [path.join(process.cwd(), 'ng2/styles.scss')],
test: /\.css$/,
use: [
'exports-loader?module.exports.toString()',
{
loader: 'raw-loader'
},
{
loader: 'postcss-loader',
options: {
ident: 'embedded',
plugins: postcssPlugins,
sourceMap: false
}
}
]
},
{
exclude: [path.join(process.cwd(), 'src\\styles.css')],
test: /\.scss$|\.sass$/,
use: [
{
loader: 'raw-loader'
},
{
loader: 'postcss-loader',
options: {
ident: 'embedded',
plugins: postcssPlugins,
sourceMap: false
}
},
{
loader: 'sass-loader',
options: {
sourceMap: false,
precision: 8,
includePaths: []
}
}
]
},
{
exclude: [path.join(process.cwd(), 'src\\styles.css')],
test: /\.less$/,
use: [
{
loader: 'raw-loader'
},
{
loader: 'postcss-loader',
options: {
ident: 'embedded',
plugins: postcssPlugins,
sourceMap: false
}
},
{
loader: 'less-loader',
options: {
sourceMap: false
}
}
]
},
{
exclude: [path.join(process.cwd(), 'src\\styles.css')],
test: /\.styl$/,
use: [
{
loader: 'raw-loader'
},
{
loader: 'postcss-loader',
options: {
ident: 'embedded',
plugins: postcssPlugins,
sourceMap: false
}
},
{
loader: 'stylus-loader',
options: {
sourceMap: false,
paths: []
}
}
]
},
{
include: [path.join(process.cwd(), 'src\\styles.css')],
test: /\.css$/,
loaders: ExtractTextPlugin.extract({
use: [
{
loader: 'raw-loader'
},
{
loader: 'postcss-loader',
options: {
ident: 'extracted',
plugins: postcssPlugins,
sourceMap: false
}
}
],
publicPath: ''
})
},
{
include: [path.join(process.cwd(), 'src\\styles.css')],
test: /\.scss$|\.sass$/,
loaders: ExtractTextPlugin.extract({
use: [
{
loader: 'raw-loader'
},
{
loader: 'postcss-loader',
options: {
ident: 'extracted',
plugins: postcssPlugins,
sourceMap: false
}
},
{
loader: 'sass-loader',
options: {
sourceMap: false,
precision: 8,
includePaths: []
}
}
],
publicPath: ''
})
},
{
include: [path.join(process.cwd(), 'src\\styles.css')],
test: /\.less$/,
loaders: ExtractTextPlugin.extract({
use: [
{
loader: 'raw-loader'
},
{
loader: 'postcss-loader',
options: {
ident: 'extracted',
plugins: postcssPlugins,
sourceMap: false
}
},
{
loader: 'less-loader',
options: {
sourceMap: false
}
}
],
publicPath: ''
})
},
{
include: [path.join(process.cwd(), 'src\\styles.css')],
test: /\.styl$/,
loaders: ExtractTextPlugin.extract({
use: [
{
loader: 'raw-loader'
},
{
loader: 'postcss-loader',
options: {
ident: 'extracted',
plugins: postcssPlugins,
sourceMap: false
}
},
{
loader: 'stylus-loader',
options: {
sourceMap: false,
paths: []
}
}
],
publicPath: ''
})
},
{
include: babelFiles,
test: /\.(js)$/,
use: {
loader: 'babel-loader',
options: {
babelrc: true
}
}
},
{
test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
use: [
{
loader: '@angular-devkit/build-optimizer/webpack-loader',
options: {
sourceMap: false
}
},
'@ngtools/webpack'
]
}
]
},
plugins: [
new NoEmitOnErrorsPlugin(),
new CopyWebpackPlugin(
[
{
context: 'src',
to: '',
from: {
glob: 'assets\\**\\*',
dot: true
}
},
{
context: 'src',
to: '',
from: {
glob: 'favicon.ico',
dot: true
}
}
],
{
ignore: ['.gitkeep', '**/.DS_Store', '**/Thumbs.db'],
debug: 'warning'
}
),
new ProgressPlugin(),
new CircularDependencyPlugin({
exclude: /(\\|\/)node_modules(\\|\/)/,
failOnError: false,
onDetected: false,
cwd: projectRoot
}),
new HtmlWebpackPlugin({
template: './pre-index.html',
filename: './index.html',
hash: false,
inject: true,
compile: true,
favicon: false,
minify: false,
cache: true,
showErrors: true,
chunks: 'all',
excludeChunks: ['scripts-login', 'ng1'],
title: 'Webpack App',
xhtml: true,
chunksSortMode: function sort(left, right) {
const leftIndex = entryPoints.indexOf(left.names[0])
const rightIndex = entryPoints.indexOf(right.names[0])
if (leftIndex > rightIndex) {
return 1
} else if (leftIndex < rightIndex) {
return -1
} else {
return 0
}
}
}),
new HtmlWebpackPlugin({
template: './pre-login.html',
filename: './login.html',
hash: false,
inject: true,
compile: true,
favicon: false,
minify: false,
cache: true,
showErrors: true,
chunks: ['inline', 'ng1', 'scripts-login'],
excludeChunks: [],
title: 'Webpack App',
xhtml: true,
chunksSortMode: function sort(left, right) {
const leftIndex = entryPointsLogin.indexOf(left.names[0])
const rightIndex = entryPointsLogin.indexOf(right.names[0])
if (leftIndex > rightIndex) {
return 1
} else if (leftIndex < rightIndex) {
return -1
} else {
return 0
}
}
}),
new BaseHrefWebpackPlugin({}),
new ExtractTextPlugin({
filename: '[name].[contenthash:20].bundle.css'
}),
new CleanCssWebpackPlugin(),
new EnvironmentPlugin({
NODE_ENV: 'production'
}),
new HashedModuleIdsPlugin({
hashFunction: 'md5',
hashDigest: 'base64',
hashDigestLength: 4
}),
new ModuleConcatenationPlugin({}),
new BundleBudgetPlugin({}),
// new LicenseWebpackPlugin({
// licenseFilenames: ['LICENSE', 'LICENSE.md', 'LICENSE.txt', 'license', 'license.md', 'license.txt'],
// perChunkOutput: false,
// outputTemplate: path.join(process.cwd(), 'node_modules\\license-webpack-plugin\\output.template.ejs'),
// outputFilename: '3rdpartylicenses.txt',
// suppressErrors: true,
// includePackagesWithoutLicense: false,
// abortOnUnacceptableLicense: false,
// addBanner: false,
// bannerTemplate: '/*! 3rd party license information is available at <%- filename %> */',
// includedChunks: [],
// excludedChunks: [],
// additionalPackages: [],
// pattern: /^(MIT|ISC|BSD.*)$/
// }),
new PurifyPlugin(),
new UglifyJsPlugin({
test: /\.js$/i,
extractComments: false,
sourceMap: false,
cache: true,
parallel: true,
uglifyOptions: {
output: {
ascii_only: true,
comments: false,
webkit: true
},
ecma: 5,
warnings: false,
ie8: false,
mangle: {
safari10: true
},
compress: {
typeofs: false,
pure_getters: true,
passes: 3
}
}
}),
new AngularCompilerPlugin({
mainPath: 'main.ts',
platform: 0,
hostReplacementPaths: {
'environments/environment.ts': `environments/environmentdevelopment.ts`
},
sourceMap: false,
tsConfigPath: 'ng2/tsconfig.app.json',
compilerOptions: {}
})
],
node: {
fs: 'empty',
global: true,
crypto: 'empty',
tls: 'empty',
net: 'empty',
process: true,
module: false,
clearImmediate: false,
setImmediate: false
},
devServer: {
compress: true,
historyApiFallback: true,
compress: true,
proxy: {
'/oms': {
target: 'http://localhost:8080',
bypass: function(req, res, proxyOptions) {
if (req && req.url) {
// console.log('current url', req.url);
if (req.url.indexOf('/oms/index.html') !== -1 || req.url === '/oms/') {
console.log('catched', req.url)
return '/index.html'
} else if (req.url.indexOf('/oms/login.html') !== -1) {
console.log('catched', req.url)
return '/login.html'
}
}
}
}
}
}
}