Created
November 19, 2024 07:37
-
-
Save relyky/aa465eea1f9071f29b95b90af918bd44 to your computer and use it in GitHub Desktop.
webpack.config.js 應用留存
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 與 webpack.config.lazy.js 搭配,以進行動態拆分。 | |
import React, { lazy, Suspense, LazyExoticComponent, useMemo } from "react" | |
type ComponentType = LazyExoticComponent<React.ComponentType<any>>; | |
//## 所有作業都需先“註冊” | |
const funcPool = new Map<string, ComponentType>(); | |
funcPool.set("HomeIndex", lazy(() => import(/* webpackChunkName: "HomeIndex" */'./Home/HomeIndex'))); | |
funcPool.set("DEMO001", lazy(() => import(/* webpackChunkName: "DEMO001" */'./Demo/DEMO001/AppForm'))); | |
funcPool.set("DEMO002", lazy(() => import(/* webpackChunkName: "DEMO002" */'./Demo/DEMO002/AppForm'))); | |
//※ 上面的 webpackChunkName 註解資訊將在 bundle 時送至 webpack.config.js 對應的 chunk 參數 [name] 以用於 chunk.bundle.js 取名。 | |
export default function AppMain(props: { | |
funcId: string | |
}) { | |
//## 依參數 funcId 取得 AppCtx | |
const AppCtx = useMemo(() => funcPool.get(props.funcId) ?? funcPool.get('HomeIndex') | |
, [funcPool, props.funcId]) | |
console.log('App.AppForm.v1', { props }) | |
return ( | |
<div> | |
<h1>AppForm</h1> | |
<a href="/">Home</a> | |
<a href="/Demo/DEMO001">DEMO001</a> | |
<a href="/Demo/DEMO002">DEMO002</a> | |
<main> | |
<Suspense fallback={<Spinner />}> | |
<AppCtx /> | |
</Suspense> | |
</main> | |
</div> | |
) | |
} | |
const Spinner: React.FC = () => ( | |
<div className="text-center bg-light text-primary p-4 "> | |
<i className="fa fa-cog fa-spin fa-5x"></i> | |
<p>載入中</p> | |
</div> | |
) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 單進入點與動態 lazy 載入。 | |
* 應用於 "webpack": "^5.88.2", "webpack-cli": "^5.1.4", "react": "^18.3.1", "react-dom": "^18.3.1", | |
* 需挑配 React lazy 指令進行動態拆分。 | |
*/ | |
//const HtmlWebPackPlugin = require("html-webpack-plugin"); | |
const path = require('path'); | |
const TerserPlugin = require('terser-webpack-plugin'); | |
module.exports = [{ | |
context: __dirname, | |
entry: { | |
app: './src/app.tsx', | |
}, | |
output: { | |
path: path.resolve(__dirname, '../N48MvcReactLab/Scripts/bundle/'), | |
filename: '[name].bundle.js', | |
publicPath: '/Scripts/bundle/', | |
chunkFilename: '[name].bundle.js' | |
}, | |
module: { | |
rules: [ | |
{ | |
test: /\.?js$/, | |
exclude: /node_modules/, | |
use: { | |
loader: "babel-loader", | |
options: { | |
presets: ["@babel/preset-env", "@babel/preset-react"], | |
}, | |
}, | |
}, | |
{ | |
test: /\.tsx?$/, | |
use: 'ts-loader', | |
exclude: /node_modules/ | |
}, | |
{ | |
test: /\.css$/, | |
use: [ | |
"style-loader", | |
"css-loader", | |
], | |
}, | |
], | |
}, | |
resolve: { | |
extensions: ['.tsx', '.ts', '.js'], | |
alias: { | |
hooks: path.resolve(__dirname, 'src/hooks/'), | |
} | |
}, | |
optimization: { | |
// minimize: true, // 預設當執行[webpack --mode production]模式指令時會觸發[minimizer]動作。 | |
minimizer: [ | |
/* Remove Comment, ref→https://webpack.js.org/plugins/terser-webpack-plugin/ */ | |
new TerserPlugin({ | |
terserOptions: { | |
output: { | |
comments: false, | |
}, | |
}, | |
extractComments: false, | |
}), | |
], | |
} | |
//plugins: [ | |
// new HtmlWebPackPlugin({ | |
// template: "./src/index.html", | |
// filename: "./index.html" | |
// }) | |
//] | |
}]; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 多個進入點與分拆共用模組。 | |
* 應用於 "webpack": "^5.88.2", "webpack-cli": "^5.1.4" | |
* 但共用模組不是傳統的函式庫提供固定的參數,就算沒有用到也放著。 | |
* 本例 webpack 拆出來的共用模組 shared, common, highorder 其內容是有用到才放入,bundle 混淆後識別代碼名稱也會動態換掉。 | |
*/ | |
const path = require("path"); | |
const TerserPlugin = require('terser-webpack-plugin'); // 用以不產生 LICENSE 宣告檔 | |
const Dotenv = require('dotenv-webpack'); // 用以取得 .env 環境參數 | |
module.exports = { | |
mode: "production", // development | production | |
entry: { | |
common: { | |
import: './src/common/index.tsx', | |
dependOn: ['shared'], | |
}, | |
highorder: { | |
import: './src/highorder/index.tsx', | |
dependOn: ['shared', 'common'], | |
}, | |
home: { | |
import: "/src/home/app.tsx", //default: "/src/index.js" | |
dependOn: ['shared','common', 'highorder'], | |
}, | |
demo001: { | |
import: '/src/Demo/DEMO001/app.tsx', | |
dependOn: ['shared', 'common', 'highorder'], | |
}, | |
demo002: { | |
import: '/src/Demo/DEMO002/app.tsx', | |
dependOn: ['shared', 'common', 'highorder'], | |
}, | |
demo003: { | |
import: '/src/Demo/DEMO003/app.tsx', | |
dependOn: ['shared', 'common', 'highorder'], | |
}, | |
shared: 'lodash', // 動態共享模組 | |
}, | |
output: { | |
path: path.resolve(__dirname, "../N48MvcReactTpl/Scripts/bundle"), // output folder, default:"./dist" | |
publicPath: "/", | |
filename: "[name].bundle.js", | |
}, | |
optimization: { | |
runtimeChunk: 'single', | |
minimize: true, | |
minimizer: [ | |
new TerserPlugin({ | |
extractComments: false, // 不產生 LICENSE 宣告檔 | |
//exclude: /common|highorder/, // 不進行混淆 | |
}), | |
], | |
splitChunks: { | |
cacheGroups: { | |
// 動態共享模組 shared: 將所有在 node_modules 中的程式碼打包到 shared.bundle.js。 | |
shared: { | |
name: 'shared', | |
test: /[\\/]node_modules[\\/]/, | |
chunks: 'all', | |
enforce: true, | |
}, | |
//// 動態共享模組 common: 將 src\highorder 等共用中的程式碼打包到 common.bundle.js。 | |
//common: { | |
// name: 'common', | |
// test: /[\\/]src[\\/](highorder|tools|hooks|atoms|shared)[\\/]/, | |
// chunks: 'all', | |
// enforce: true, | |
//}, | |
}, | |
}, | |
}, | |
resolve: { | |
extensions: ['.tsx', '.ts', '.js'] | |
}, | |
module: { | |
rules: [ | |
{ | |
test: /\.?js$/, | |
exclude: /node_modules/, | |
use: { | |
loader: "babel-loader", | |
options: { | |
presets: ["@babel/preset-env", "@babel/preset-react"], | |
}, | |
}, | |
}, | |
{ | |
test: /\.tsx?$/, | |
use: 'ts-loader', | |
exclude: /node_modules/ | |
}, | |
{ | |
test: /\.css$/, | |
use: [ | |
"style-loader", | |
"css-loader", | |
], | |
}, | |
], | |
}, | |
plugins: [ | |
new Dotenv({ | |
path: './.env', | |
systemvars: true, | |
defaults: true | |
}) | |
], | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment