javascript - Webpack 外部无法在父项目中解析
问题描述
我有一个库,这个库是 React 组件库,所以它依赖于react
和react-dom
. 它还取决于react-router-dom
(和传递react-router
)。
这些是父项目提供的包。我不希望它们在捆绑包中。该库是使用 webpack 生成的,因此我已将它们添加到externals
库 webpack 配置中的配置中,如下所示(Webpack v4.4)
const webpack = require("webpack");
const path = require("path");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
module.exports = {
entry: "./src/index.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist"),
libraryTarget: "commonjs",
},
externals: {
"react-router": {
"commonjs": "react-router",
"commonjs2": "eact-router",
"amd": "react-router",
"root": "react-router"
},
"react-router-dom": {
"commonjs": "react-router-dom",
"commonjs2": "react-router-dom",
"amd": "react-router-dom",
"root": "react-router-dom"
},
"react": {
"commonjs": "react",
"commonjs2": "react",
"amd": "react",
"root": "React"
},
"react-dom": {
"commonjs": "react-dom",
"commonjs2": "react-dom",
"amd": "react-dom",
"root": "ReactDOM"
}
},
// devtool: "cheap-eval-source-map",
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env", "@babel/preset-react"],
plugins: [
"@babel/plugin-transform-flow-strip-types",
"@babel/plugin-proposal-object-rest-spread",
"transform-class-properties",
],
},
},
},
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: [
{ loader: "css-loader", options: { minify: true } },
"sass-loader",
],
}),
},
{
// Match woff2 in addition to patterns like .woff?v=1.1.1.
test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: "url-loader",
options: {
// Limit at 50k. Above that it emits separate files
limit: 50000,
// url-loader sets mimetype if it's passed.
// Without this it derives it from the file extension
mimetype: "application/font-woff",
// Output below fonts directory
name: "./fonts/[name].[ext]",
},
},
],
},
{
test: /\.svg$/,
use: [
{
loader: "svg-inline-loader",
options: {
removeSVGTagAttrs: false,
},
},
],
},
{
test: /\.(png|jp(e*)g)$/,
use: [{
loader: 'url-loader',
options: {
limit: 8000, // Convert images < 8kb to base64 strings
name: 'images/[hash]-[name].[ext]'
}
}]
},
],
},
plugins: [
new ExtractTextPlugin("styles.css"),
new OptimizeCssAssetsPlugin({
assetNameRegExp: /\.optimize\.css$/g,
cssProcessor: require("cssnano"),
cssProcessorOptions: { discardComments: { removeAll: true } },
canPrint: true,
}),
new webpack.optimize.AggressiveMergingPlugin(),
],
};
但是,当我在父项目中包含库的输出时,它会在构建阶段抱怨
ERROR in ../moss/dist/bundle.js
Module not found: Error: Can't resolve 'react-router' in '/Users/ubermouse/code/moss/dist'
@ ../moss/dist/bundle.js 19655:223-261
@ ./matai/static_src/js/containers/App.js
@ ./matai/static_src/js/containers/Root.js
@ ./matai/static_src/js/index.js
@ multi ./matai/static_src/js/utils/polyfills.js ./matai/static_src/js/index.js
我得到了 react-router 和 react-router-dom 的上述错误。我没有得到它的反应或反应域。
这里发生了什么?我使用外部错误吗?为什么它适用于 react/react-dom?他们只是还不需要吗?外部不能从父节点模块中提取依赖项吗?我已经为此扯了几个小时的头发了:(
我注意到一件事,react-router/react-router-dommodule
在他们的 package.json 中有一个属性,所以他们的 ESModule 被加载了。react/react-router 没有。我不知道这是否会改变任何东西,但它确实是。
为了完整性,我们的父项目 webpack 配置
const webpack = require('webpack');
const path = require('path');
const config = require('./frontend.config');
/**
* Base Webpack config, defining how our code should compile.
*/
module.exports = {
entry: {
vendor: [
"moment",
"react",
"react-dom",
"react-intl",
"react-intl-redux",
"react-redux",
"react-leaflet",
"react-router",
"react-router-dom",
"react-router-redux",
"redux",
"redux-observable",
"rxjs",
],
matai: [
path.join(config.paths.js, 'utils', 'polyfills.js'),
path.join(config.paths.js, 'index.js'),
],
},
output: {
path: path.join(config.paths.build_js),
filename: '[name].js',
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: "vendor",
minChunks: Infinity,
// (with more entries, this ensures that no other module
// goes into the vendor chunk)
}),
],
module: {
rules: [
// Disable require.ensure as it's not a standard language feature.
{ parser: { requireEnsure: false } },
// First, run the linter.
// It's important to do this before Babel processes the JS.
{
test: /\.js$/,
enforce: 'pre',
use: ['eslint-loader'],
include: path.join(config.paths.js),
},
{
test: /\.js$/,
use: ['babel-loader'],
exclude: [/node_modules/],
},
],
},
stats: {
// Set the maximum number of modules to be shown
maxModules: 3,
// Add chunk information (setting this to `false` allows for a less verbose output)
chunks: false,
// Add the hash of the compilation
hash: false,
// `webpack --colors` equivalent
colors: true,
// Add information about the reasons why modules are included
reasons: false,
// Add webpack version information
version: false,
},
// Some libraries import Node modules but don't use them in the browser.
// Tell Webpack to provide empty mocks for them so importing them works.
node: {
fs: 'empty',
net: 'empty',
tls: 'empty',
},
};
解决方案
推荐阅读
- reactjs - React Native:插件/预设文件不允许导出对象,只能导出函数
- python - 如何使用 Selenium 和 Python 单击 svg 标记中的下拉按钮
- javascript - 在数据之间解析带有 \n 的 csv 文件
- python - 如何解决 kivy python 中的“AttributeError”?
- java - 通过改造获取嵌套的 JSON 数组?
- javascript - 我无法在从子组件登录/注销时重新渲染 app.js
- sed - 替换匹配字符串中的子字符串
- sql - 我可以将输入的值以及选定的数据插入到临时表中吗?
- javascript - 无法使用另一个对象数组更新对象数组
- python - 如何从 Python 运行 Word 宏?