I had ended up doing some refactoring around routes to allow for code splitting but following the react/webpack instructions I've still got just the 2 entry bundles being generated.
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/**/*",
],
}
I expected a new chunk to be generated for the EconomyManager
lazy import but the build only generates a main.[hash].js
and semantic.[hash].js
. Where am I going wrong here?
I checked and EconomyManager
exports are not being referenced anywhere else in the application as I thought that might be it.
@babel/preset-env
might be transpiling your dynamic imports to deferred requires, this will prevent Webpack from knowing where to code split.
We will need to exclude the plugin @babel/plugin-proposal-dynamic-import
so your import()
statements are preserved. Try adding the exclude field to your @babel/preset-env
options in your Webpack config.
presets: [['@babel/preset-env', { useBuiltIns: 'entry', corejs: '3.0.0', exclude: ['proposal-dynamic-import'] }]
This is described in similar GitHub Issues:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With