我们刚刚从webpack1迁移到webpack2,升级后有些样式无法正确呈现。
当我查看开发控制台中当前已损坏的DOM元素时,我看到现在控制台正在显示实际文件的路径,而在旧版本中它只是显示文件名。此外,当悬停在文件名上时,它将显示相对路径,但以' webpack:///.src/..'
开头以下是devconsole的两个独立屏幕截图,以显示我的意思:
以下是两个webpack配置文件:
import webpack from 'webpack';
import autoprefixer from 'autoprefixer';
import cssnano from 'cssnano';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import config from '../config';
import _debug from 'debug';
const debug = _debug('app:webpack:config');
const paths = config.utils_paths;
const {__DEV__, __PROD__, __TEST__} = config.globals;
debug('Create configuration.');
const webpackConfig = {
name: 'client',
target: 'web',
devtool: 'source-map',
resolve: {
modules: [
paths.base(config.dir_client),
'node_modules'
],
extensions: ['.js', '.jsx']
},
module: {}
};
// ------------------------------------
// Entry Points
// ------------------------------------
const APP_ENTRY_PATH = paths.base(config.dir_client) + '/main.js';
webpackConfig.entry = {
app: __DEV__
? [APP_ENTRY_PATH, `webpack-hot-middleware/client?path=${config.compiler_public_path}__webpack_hmr`]
: [APP_ENTRY_PATH],
bootstrap: 'bootstrap-loader',
vendor: config.compiler_vendor
};
// ------------------------------------
// Bundle Output
// ------------------------------------
webpackConfig.output = {
filename: `[name].[${config.compiler_hash_type}].js`,
path: paths.base(config.dir_dist),
publicPath: config.compiler_public_path
};
// ------------------------------------
// Plugins
// ------------------------------------
webpackConfig.plugins = [
new webpack.DefinePlugin(config.globals),
new webpack.ProvidePlugin({
'jQuery': 'jquery',
'$': 'jquery'
}),
new HtmlWebpackPlugin({
template: paths.client('index.html'),
hash: false,
favicon: paths.client('static/favicon.ico'),
filename: 'index.html',
inject: 'body',
minify: {
collapseWhitespace: true
}
})
];
if (__DEV__) {
debug('Enable plugins for live development (HMR, NoErrors).');
webpackConfig.plugins.push(
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin()
);
} else if (__PROD__) {
debug('Enable plugins for production (UglifyJS).');
webpackConfig.plugins.push(
new webpack.optimize.UglifyJsPlugin({
compress: {
unused: true,
dead_code: true,
warnings: false
}
})
);
}
// Don't split bundles during testing, since we only want import one bundle
if (!__TEST__) {
webpackConfig.plugins.push(
new webpack.optimize.CommonsChunkPlugin({
names: ['vendor']
})
);
}
// ------------------------------------
// This used to be called 'Pre-Loaders'. Now 'Rules' enforcing 'pre'
// ------------------------------------
webpackConfig.module.rules = [
{
test: /\.(js|jsx)$/,
enforce: 'pre',
loader: 'eslint-loader',
include: /src/,
options: {
configFile: paths.base('.eslintrc'),
emitWarning: __DEV__
}
}
];
// ------------------------------------
// Used to be called 'Loaders'. Now 'Rules'
// ------------------------------------
// JavaScript / JSON
webpackConfig.module.rules.push({
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: [
{ loader: 'babel-loader',
options: {
cacheDirectory: true,
plugins: ['transform-runtime'],
presets: __DEV__
? ['es2015', 'react', 'stage-0', 'react-hmre']
: ['es2015', 'react', 'stage-0']
}
}
]
});
// Styles
const cssLoader = !config.compiler_css_modules
? {loader: 'css-loader', options: {sourceMap: true}}
: {loader: 'css-loader',
options: {
modules: true,
sourceMap: true,
importLoaders: 1,
localIdentName: '[name]__[local]___[hash:base64:5]'
}};
const postCssLoader = {
loader: 'postcss-loader',
options: {
plugins: () => [
autoprefixer({
add: true,
remove: true,
browsers: ['last 2 versions']
}),
cssnano(
{preset:
['default',
{
discardComments: {
removeAll: true
}
}
]
})],
safe: true,
sourceMap: true
}
};
webpackConfig.module.rules.push({
test: /\.scss$/,
include: /src/,
use: [
'style-loader',
cssLoader,
postCssLoader,
{loader: 'sass-loader', options: {sourceMap: true, includePaths: [paths.client('styles')]}}
]
});
webpackConfig.module.rules.push({
test: /\.css$/,
include: /src/,
use: [
'style-loader',
cssLoader,
postCssLoader
]
});
// Don't treat global SCSS as modules
webpackConfig.module.rules.push({
test: /\.scss$/,
exclude: /src/,
use: [
'style-loader',
'css-loader?sourceMap',
postCssLoader,
{loader: 'sass-loader', options: {sourceMap: true, includePaths: [paths.client('styles')]}}
]
});
// Don't treat global, third-party CSS as modules
webpackConfig.module.rules.push({
test: /\.css$/,
exclude: /src/,
use: [
'style-loader',
'css-loader?sourceMap',
postCssLoader
]
});
// File loaders
/* eslint-disable */
webpackConfig.module.rules.push(
{ test: /\.woff(\?.*)?$/, loader: 'url-loader?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=application/font-woff' },
{ test: /\.woff2(\?.*)?$/, loader: 'url-loader?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=application/font-woff2' },
{ test: /\.otf(\?.*)?$/, loader: 'file-loader?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=font/opentype' },
{ test: /\.ttf(\?.*)?$/, loader: 'url-loader?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=application/octet-stream' },
{ test: /\.eot(\?.*)?$/, loader: 'file-loader?prefix=fonts/&name=[path][name].[ext]' },
{ test: /\.svg(\?.*)?$/, loader: 'url-loader?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=image/svg+xml' },
{ test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192' }
)
/* eslint-enable */
export default webpackConfig;
import webpack from 'webpack';
import cssnano from 'cssnano';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import config from '../config';
import _debug from 'debug';
const debug = _debug('app:webpack:config');
const paths = config.utils_paths;
const {__DEV__, __PROD__, __TEST__} = config.globals;
debug('Create configuration.');
const webpackConfig = {
name: 'client',
target: 'web',
devtool: 'source-map',
resolve: {
root: paths.base(config.dir_client),
extensions: ['', '.js', '.jsx']
},
module: {}
};
// ------------------------------------
// Entry Points
// ------------------------------------
const APP_ENTRY_PATH = paths.base(config.dir_client) + '/main.js';
webpackConfig.entry = {
app: __DEV__
? [APP_ENTRY_PATH, `webpack-hot-middleware/client?path=${config.compiler_public_path}__webpack_hmr`]
: [APP_ENTRY_PATH],
bootstrap: 'bootstrap-loader',
vendor: config.compiler_vendor
};
// ------------------------------------
// Bundle Output
// ------------------------------------
webpackConfig.output = {
filename: `[name].[${config.compiler_hash_type}].js`,
path: paths.base(config.dir_dist),
publicPath: config.compiler_public_path
};
// ------------------------------------
// Plugins
// ------------------------------------
webpackConfig.plugins = [
new webpack.DefinePlugin(config.globals),
new webpack.ProvidePlugin({
'jQuery': 'jquery',
'$': 'jquery',
}),
new HtmlWebpackPlugin({
template: paths.client('index.html'),
hash: false,
favicon: paths.client('static/favicon.ico'),
filename: 'index.html',
inject: 'body',
minify: {
collapseWhitespace: true
}
})
];
if (__DEV__) {
debug('Enable plugins for live development (HMR, NoErrors).');
webpackConfig.plugins.push(
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
);
} else if (__PROD__) {
debug('Enable plugins for production (OccurenceOrder, Dedupe & UglifyJS).');
webpackConfig.plugins.push(
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin({
compress: {
unused: true,
dead_code: true,
warnings: false
}
})
);
}
// Don't split bundles during testing, since we only want import one bundle
if (!__TEST__) {
webpackConfig.plugins.push(
new webpack.optimize.CommonsChunkPlugin({
names : ['vendor']
})
)
}
// ------------------------------------
// Pre-Loaders
// ------------------------------------
webpackConfig.module.preLoaders = [{
test: /\.(js|jsx)$/,
loader: 'eslint',
exclude: /node_modules/
}];
webpackConfig.eslint = {
configFile: paths.base('.eslintrc'),
emitWarning: __DEV__
};
// ------------------------------------
// Loaders
// ------------------------------------
// JavaScript / JSON
webpackConfig.module.loaders = [{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: 'babel',
query: {
cacheDirectory: true,
plugins: ['transform-runtime'],
presets: __DEV__
? ['es2015', 'react', 'stage-0', 'react-hmre']
: ['es2015', 'react', 'stage-0']
}
},
{
test: /\.json$/,
loader: 'json'
}
];
// Styles
const cssLoader = !config.compiler_css_modules
? 'css?sourceMap'
: [
'css?modules',
'sourceMap',
'importLoaders=1',
'localIdentName=[name]__[local]___[hash:base64:5]'
].join('&');
webpackConfig.module.loaders.push({
test: /\.scss$/,
include: /src/,
loaders: [
'style',
cssLoader,
'postcss',
'sass?sourceMap'
]
});
webpackConfig.module.loaders.push({
test: /\.css$/,
include: /src/,
loaders: [
'style',
cssLoader,
'postcss'
]
});
// Don't treat global SCSS as modules
webpackConfig.module.loaders.push({
test: /\.scss$/,
exclude: /src/,
loaders: [
'style',
'css?sourceMap',
'postcss',
'sass?sourceMap'
]
});
// Don't treat global, third-party CSS as modules
webpackConfig.module.loaders.push({
test: /\.css$/,
exclude: /src/,
loaders: [
'style',
'css?sourceMap',
'postcss'
]
});
webpackConfig.sassLoader = {
includePaths: paths.client('styles')
};
webpackConfig.postcss = [
cssnano({
autoprefixer: {
add: true,
remove: true,
browsers: ['last 2 versions']
},
discardComments: {
removeAll: true
},
safe: true,
sourcemap: true
})
];
// File loaders
/* eslint-disable */
webpackConfig.module.loaders.push(
{ test: /\.woff(\?.*)?$/, loader: 'url?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=application/font-woff' },
{ test: /\.woff2(\?.*)?$/, loader: 'url?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=application/font-woff2' },
{ test: /\.otf(\?.*)?$/, loader: 'file?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=font/opentype' },
{ test: /\.ttf(\?.*)?$/, loader: 'url?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=application/octet-stream' },
{ test: /\.eot(\?.*)?$/, loader: 'file?prefix=fonts/&name=[path][name].[ext]' },
{ test: /\.svg(\?.*)?$/, loader: 'url?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=image/svg+xml' },
{ test: /\.(png|jpg)$/, loader: 'url?limit=8192' }
)
/* eslint-enable */
export default webpackConfig;
config
文件未更改。我查看了webpack2文档,但不确定要像以前一样设置样式解析。我已经尝试resolve.mainFiles
指向曾经是resolve.root
的内容,但这会导致构建错误。我也尝试output.devtoolModuleFilenameTemplate
为webpack:///[resource-path]?[loaders]
,但绝对路径仍然存在。
' webpack:///'有什么意义?文件前缀与绝对文件路径?我应该转换为相对路径吗?我该怎么做?
答案 0 :(得分:0)
我认为这是关于source-maps
个文件的?
所以,当我调试JS时,文件加载为webpack:///
,但之后我使用Cmd+o
通过source-map打开文件,我能够打开文件。
答案 1 :(得分:0)
我找了一会儿,把它交给了一位同事后来发现css-loader现在正在使用abs路径:https://github.com/webpack-contrib/css-loader/releases/tag/v0.26.4
我发表了评论:https://github.com/webpack-contrib/css-loader/pull/430#issuecomment-326002386