为啥 webpack 没有从我的动态导入中生成块?
Posted
技术标签:
【中文标题】为啥 webpack 没有从我的动态导入中生成块?【英文标题】:Why is webpack not generating chunks from my dynamic imports?为什么 webpack 没有从我的动态导入中生成块? 【发布时间】:2020-03-25 10:51:42 【问题描述】:我最终围绕路由进行了一些重构以允许代码拆分,但按照 react/webpack 说明,我仍然只生成了 2 个入口包。
Index.tsx
import React from "react"
import render from "react-dom"
import Provider from "react-redux"
import store from "services/configureStore"
import ConnectedApp from "src/App"
import ConnectedFeatureToggleProvider from "./components/AppWrapper/FeatureToggleProvider"
const renderApp = () =>
render(
<Provider store=store>
<ConnectedFeatureToggleProvider>
<ConnectedApp />
</ConnectedFeatureToggleProvider>
</Provider>,
document.querySelector("#app"),
)
// run app when FIT Core functions are ready
window.onFitCoreReady = () =>
renderApp()
App.tsx
import React, useEffect, Suspense from "react"
import hot from "react-hot-loader/root"
import connect from "react-redux"
import Switch, Redirect, Route, Router from "react-router-dom"
// import ConnectedEconomyManager from "modules/economyManager/EconomyManager"
import ConnectedPlayerAccounts from "modules/playerAccountDataManager/PlayerAccounts"
import HealthDashboard from "modules/healthDashboard/HealthDashboard"
import PackSimulator from "modules/packSimulator/PackSimulator"
const mapStateToProps = (state: GlobalState) => (
...
)
const mapDispatchToProps = (dispatch: Dispatch) => (
...
)
type Props =
const ConnectedEconomyManager = React.lazy(() => import("modules/economyManager/EconomyManager"))
export const App = (
: Props) =>
return (
<Router history=history>
<Suspense fallback=<span>LOADING LOADING LOADING</span>>
<Switch>
<Redirect
exact
from="/marketplace/"
to=
pathname: "/marketplace/economy",
search: window.location.search,
/>
<Route path="/marketplace/economy" component=ConnectedEconomyManager />
<Route path="/marketplace/playerAccounts" component=ConnectedPlayerAccounts />
<Route path="/marketplace/health" component=HealthDashboard />
<Route path="/marketplace/packSimulator" component=PackSimulator />
</Switch>
</Suspense>
</Router>
)
export const ConnectedApp = hot(connect(mapStateToProps, mapDispatchToProps)(App))
webpack/local.js
const webpack = require('webpack');
const htmlWebpackPlugin = require('html-webpack-plugin');
const merge = require('webpack-merge');
const _ = require('lodash');
const common = require('./common');
const path = require('path');
const open = process.env.npm_package_config_WEBPACK_OPEN_WINDOW === 'true';
const host = process.env.npm_package_config_WEBPACK_LOCAL_HOST;
const port = process.env.npm_package_config_WEBPACK_PORT;
const ROOT_DIR = path.resolve(__dirname, '../');
const APP_DIR = path.resolve(ROOT_DIR, 'src');
module.exports = env =>
if (!env)
// Prevent references to 'undefined'
env = ;
return merge.smart(common,
mode: 'development',
devServer:
disableHostCheck: true,
port: '443',
historyApiFallback: true,
open: open ? 'Google Chrome' : open, // auto-open in browser
openPage: 'marketplace/economy?project=' + projectName,
,
devtool: 'eval-source-map',
module:
rules: [
_.merge(
_.find(common.module.rules, rule => rule.use && rule.use.loader === 'babel-loader'),
use: options: plugins: ['@babel/plugin-syntax-dynamic-import', 'babel-plugin-styled-components', '@babel/plugin-proposal-class-properties']
),
test: /\.css$/,
use: ['style-loader', 'css-loader'],
,
test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] ,
test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] ,
],
,
plugins: [
// copies the index.html file to the build directory:
new HtmlWebpackPlugin(
template: `$APP_DIR/index.html`,
templateParameters:
...define
),
],
);
webpack/common.js
const path = require('path');
const webpack = require('webpack');
const ROOT_DIR = path.resolve(__dirname, '../');
const BUILD_DIR = path.resolve(ROOT_DIR, 'dist');
const APP_DIR = path.resolve(ROOT_DIR, 'src');
module.exports =
entry:
main: [
`$APP_DIR/index.tsx`, // main entry point to the application
],
semantic: path.resolve(ROOT_DIR, 'semantic-theme', 'semantic.less'),
,
module:
rules: [
test: /\.[j|t]sx?$/,
use:
loader: 'babel-loader',
options:
presets: [['@babel/preset-env', useBuiltIns: 'entry', corejs: '3.0.0' ], '@babel/preset-react'],
overrides: [
test: /\.tsx?$/,
presets: [['@babel/preset-env', useBuiltIns: 'entry', corejs: '3.0.0' ], '@babel/preset-react', '@babel/preset-typescript'],
,
],
,
,
include: APP_DIR,
,names
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
use: 'url-loader?limit=10000&mimetype=application/font-woff',
,
test: /\.(ttf|otf|eot|svg|png|jpe?g|gif)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
use: 'file-loader',
,
],
,
output:
path: `$BUILD_DIR`,
filename: '[name].[hash].js',
chunkFilename: '[name].[hash].js',
publicPath: '/',
,
resolve:
extensions: ['.js', '.jsx', '.ts', '.tsx'],
modules: [
ROOT_DIR,
APP_DIR,
'node_modules',
],
alias:
// tell semantic-ui-less to use our theme config
'../../theme.config$': path.resolve(ROOT_DIR, 'semantic-theme', 'theme.config'),
'react-dom': '@hot-loader/react-dom',
,
,
stats: colors: true ,
;
tsconfig.json
"compilerOptions":
"plugins": [
"name": "typescript-styled-plugin"
],
"noEmit": true,
"strict": true,
"sourceMap": true,
"noImplicitAny": false,
"noUnusedLocals": true,
"module": "esnext",
"target": "esnext",
"lib": [
"esnext",
"dom"
],
"moduleResolution": "node",
"jsx": "preserve",
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"baseUrl": ".",
"paths":
"components/*": ["src/components/*"],
"modules/*": ["src/modules/*"],
"services/*": ["src/services/*"],
,
"types": [
"react",
"jest",
]
,
"include": [
"./src/**/*",
"./@types/**/*",
],
我希望为 EconomyManager
惰性导入生成一个新块,但构建只生成一个 main.[hash].js
和 semantic.[hash].js
。我哪里错了?
我检查并发现EconomyManager
导出没有在应用程序的其他任何地方被引用,因为我认为可能是这样。
【问题讨论】:
【参考方案1】:@babel/preset-env
可能会将您的动态导入转换为延迟需求,这将阻止 Webpack 知道在哪里进行代码拆分。
我们需要排除插件@babel/plugin-proposal-dynamic-import
,以便保留您的import()
语句。尝试将排除字段添加到 Webpack 配置中的 @babel/preset-env
选项中。
presets: [['@babel/preset-env', useBuiltIns: 'entry', corejs: '3.0.0', exclude: ['proposal-dynamic-import'] ]
这在类似的 GitHub 问题中有所描述:
https://github.com/babel/babel/issues/11204 https://github.com/babel/babel/issues/10194【讨论】:
以上是关于为啥 webpack 没有从我的动态导入中生成块?的主要内容,如果未能解决你的问题,请参考以下文章
Webpack 从我的样式表中的内联 SVG 中去除标签,我不知道为啥
为啥 tailwindcss 没有在 webpack 中使用 sass 文件正确导入所有组件?
为啥我在一个 webpack 项目上得到“意外的令牌导入”,而在另一个项目上却没有?