diff --git a/core/package.json b/core/package.json index cf2c19c..3145728 100644 --- a/core/package.json +++ b/core/package.json @@ -1,6 +1,6 @@ { "name": "@kkt/ssr", - "version": "3.1.6", + "version": "3.1.7", "description": "", "license": "MIT", "main": "lib/index.js", @@ -27,8 +27,8 @@ }, "dependencies": { "@babel/core": "^7.17.8", - "@babel/runtime": "^7.17.8", "@babel/register": "^7.17.7", + "@babel/runtime": "^7.17.8", "babel-preset-react-app": "^10.0.1", "css-loader": "^6.7.1", "kkt": "^7.1.5", @@ -42,4 +42,4 @@ "webpack-node-externals": "^3.0.0", "webpackbar": "^5.0.2" } -} \ No newline at end of file +} diff --git a/core/src/index.ts b/core/src/index.ts index 6209887..f088414 100644 --- a/core/src/index.ts +++ b/core/src/index.ts @@ -2,9 +2,9 @@ process.env.FAST_REFRESH = 'false'; process.env.BUILD_PATH = "dist" - import minimist from 'minimist'; import { BuildArgs } from 'kkt'; +import { OptionsProps } from "./interface" function help() { const { version } = require('../package.json'); @@ -18,6 +18,9 @@ function help() { console.log(' --s-st, --s-split ', 'server Split code .'); console.log(' --c-st, --c-split ', 'client Split code .'); console.log(' -o, --original ', 'Use original react-scripts .'); + console.log(' -m, --minify ', 'All Minify output.'); + console.log(' --s-m, --s-minify ', 'server Minify output.'); + console.log(' --c-m, --c-minify ', 'clinet Minify output.'); console.log('\n Example:\n'); console.log(' $ \x1b[35mkkt-ssr\x1b[0m build'); @@ -33,6 +36,8 @@ function help() { interface SSRNCCArgs extends BuildArgs { "s-ne"?: boolean; + "s-m"?: boolean; + "s-minify"?: boolean; "s-nodeExternals"?: boolean, "s-st"?: boolean, "s-split"?: boolean, @@ -40,8 +45,12 @@ interface SSRNCCArgs extends BuildArgs { "c-nodeExternals"?: boolean, "c-st"?: boolean, "c-split"?: boolean, + "c-m"?: boolean; + "c-minify"?: boolean; "o"?: boolean, "original"?: boolean, + "m"?: boolean; + "minify"?: boolean, } (async () => { @@ -84,17 +93,24 @@ interface SSRNCCArgs extends BuildArgs { // 使用原始 react-scripts const original = argvs["o"] || argvs["original"] - const options = { + const mini = argvs["m"] || argvs["minify"] + + const miniServer = mini || argvs["s-m"] || argvs["s-minify"] + const miniClient = mini || argvs["c-m"] || argvs["c-minify"] + + const options: OptionsProps = { clientNodeExternals, serverNodeExternals, clientIsChunk, serverIsChunk, - original + original, + mini, + miniServer, + miniClient } - // 解决 原始情况下 PUBLIC_URL 报错 - if (argvs["PUBLIC_URL"]) { - process.env.PUBLIC_URL = argvs["PUBLIC_URL"]; - } else { + + // 解决 使用 react-scripts 原始情况下 PUBLIC_URL 报错 + if (!Reflect.has(process.env || {}, "PUBLIC_URL")) { process.env.PUBLIC_URL = ''; } diff --git a/core/src/interface.ts b/core/src/interface.ts index 321b4d8..38ad226 100644 --- a/core/src/interface.ts +++ b/core/src/interface.ts @@ -3,5 +3,8 @@ export interface OptionsProps { serverNodeExternals: boolean; serverIsChunk: boolean; clientIsChunk: boolean; - original: boolean + original: boolean, + mini: boolean + miniServer: boolean + miniClient: boolean } \ No newline at end of file diff --git a/core/src/overrides/index.ts b/core/src/overrides/index.ts index b321f5e..d5ff484 100644 --- a/core/src/overrides/index.ts +++ b/core/src/overrides/index.ts @@ -46,6 +46,8 @@ export interface OverridesProps { overridesClientWebpack?: (conf: webpack.Configuration, env: "development" | "production", options: any) => webpack.Configuration, /** 服务端配置 */ overridesServerWebpack?: (conf: webpack.Configuration, env: "development" | "production", options: any) => webpack.Configuration; + /** 公共覆盖配置 */ + overridesCommonWebpack?: (conf: webpack.Configuration, env: "development" | "production", options: any) => webpack.Configuration; // 最终的配置 overridesWebpack?: WebpackConfigFunction @@ -77,6 +79,8 @@ let overrides: OverridesProps = { overridesClientWebpack: undefined, // 自定义 server 配置设置 overridesServerWebpack: undefined, + /** 公共覆盖配置 */ + overridesCommonWebpack: undefined, // 最终自定义配置设置 overridesWebpack: undefined, // 监听配置 diff --git a/core/src/overrides/utils.ts b/core/src/overrides/utils.ts index a2bd654..ea39ea1 100644 --- a/core/src/overrides/utils.ts +++ b/core/src/overrides/utils.ts @@ -137,23 +137,8 @@ export const restOutPut = (conf: WebpackConfiguration, options: WebpackConfigura }; }; -export const addMiniCssExtractPlugin = (conf: WebpackConfiguration): WebpackConfiguration => { - return { - ...conf, - plugins: conf.plugins.concat([ - // 开发状态下没有这个 plugin - new MiniCssExtractPlugin({ - // Options similar to the same options in webpackOptions.output - // both options are optional - filename: 'static/css/[name].[contenthash:8].css', - chunkFilename: 'static/css/[name].[contenthash:8].chunk.css', - }) - ]), - } -} // loader source-map-loader - export const removeSourceMapLoader = (conf: WebpackConfiguration): WebpackConfiguration => { return { ...conf, @@ -164,7 +149,6 @@ export const removeSourceMapLoader = (conf: WebpackConfiguration): WebpackConfig } } - // node 环境 把 css 进行处理 export const restDevModuleRuleCss = (conf: WebpackConfiguration,): WebpackConfiguration => { return { @@ -179,6 +163,7 @@ export const restDevModuleRuleCss = (conf: WebpackConfiguration,): WebpackConfig /** * 1. 去除 style-loader|mini-css-extract-plugin + * 2. 修改 css-loader 配置 * */ export const getModuleCSSRules = (rules: (webpack.RuleSetRule | '...')[], shouldUseSourceMap: boolean = false) => { const newRules: any = []; diff --git a/core/src/script/utils/index.ts b/core/src/script/utils/index.ts index 67605eb..8a0a2b4 100644 --- a/core/src/script/utils/index.ts +++ b/core/src/script/utils/index.ts @@ -17,6 +17,7 @@ import { restDevModuleRuleCss, removeSourceMapLoader } from "../../overrides/utils" + const { choosePort } = require('react-dev-utils/WebpackDevServerUtils'); // 引入环境变量 require(`${reactScripts}/config/env`); @@ -25,17 +26,33 @@ require(`${reactScripts}/config/env`); const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000; const HOST = process.env.HOST || 'localhost'; -const getWebpackConfig = (newConfig: webpack.Configuration, type: "server" | "client", overrides: OverridesProps, nodeExternals: boolean, split: boolean, env: "development" | "production", isWebpackDevServer: boolean) => { + +export type GetWebpackConfig = ( + newConfig: webpack.Configuration, + type: "server" | "client", + overrides: OverridesProps, + nodeExternals: boolean, + split: boolean, + env: "development" | "production", + isWebpackDevServer: boolean, + options: OptionsProps +) => webpack.Configuration + + +const getWebpackConfig: GetWebpackConfig = (newConfig, type, overrides, nodeExternals, split, env, isWebpackDevServer, options) => { + /** 入口 */ newConfig.entry = overrides[`${type}_path`] + /** 加载 进度条 plugin */ newConfig = getWbpackBarPlugins(newConfig, { name: type, }) + /** 输出配置 */ const out: webpack.Configuration["output"] = { filename: `${type}.js`, path: overrides.output_path, } - if (type === "server") { + /** 输出 类型 */ out.library = { type: "commonjs2" } } @@ -44,19 +61,21 @@ const getWebpackConfig = (newConfig: webpack.Configuration, type: "server" | "cl const httpPath = `http://${HOST}:${PORT}` - newConfig = restOutPut(newConfig, out) - + /** start 命令时候 配置前缀 为 devServer 端口 */ if (isWebpackDevServer && env === "development") { - newConfig.output.publicPath = `${httpPath}/` + out.publicPath = `${httpPath}/` } else { - newConfig.output.publicPath = `/` + out.publicPath = `/` } + /** 重置 输入配置 */ + newConfig = restOutPut(newConfig, out) + let isCreateAsset = false; if (isWebpackDevServer && type === "client" && env === "development") { isCreateAsset = true } - + /** start 命令下 生成 server.js文件和 自动启动 server.js 服务 */ if (isWebpackDevServer && type === "server" && env === "development") { newConfig.plugins.push( new DevServerPlugins({ @@ -69,91 +88,137 @@ const getWebpackConfig = (newConfig: webpack.Configuration, type: "server" | "cl }), ) } - + /** 重置 asset-manifest.json 文件内容 */ newConfig = restWebpackManifestPlugin(newConfig, overrides.paths, type, isCreateAsset, httpPath) - + /** 清除 html 模板方面的 plugin **/ newConfig = clearHtmlTemp(newConfig) newConfig.module.exprContextCritical = false; + + const define = { + OUTPUT_PUBLIC_PATH: JSON.stringify(overrides.output_path), + KKT_PUBLIC_DIR: JSON.stringify(process.env.KKT_PUBLIC_DIR || overrides.output_path), + HOST: JSON.stringify(HOST), + PORT: JSON.stringify(PORT), + Dev_Server: JSON.stringify(isWebpackDevServer), + HOSTAPI: JSON.stringify(undefined), + "process.env.PORT": JSON.stringify(PORT), + "process.env.HOSTAPI": JSON.stringify(undefined), + "process.env.HOST": JSON.stringify(HOST) + } + + if (isWebpackDevServer) { + // 代理 服务的 ip 地址 + define.HOSTAPI = JSON.stringify(`http://${HOST}:${PORT}`) + define["process.env.HOSTAPI"] = JSON.stringify(`http://${HOST}:${PORT}`) + } + newConfig.plugins.push( - new webpack.DefinePlugin({ - OUTPUT_PUBLIC_PATH: JSON.stringify(overrides.output_path), - HOST: JSON.stringify(HOST), - PORT: JSON.stringify(PORT), - Dev_Server: JSON.stringify(isWebpackDevServer), - "process.env.PORT": JSON.stringify(PORT || 3000), - "process.env.HOST": JSON.stringify(HOST || "localhost"), - "process.env.PUBLIC_URL": JSON.stringify(process.env.PUBLIC_URL || overrides.output_path || "") - }), + new webpack.DefinePlugin(define), ) if (!split) { + // 代码是否进行分割 newConfig.plugins.push(new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 })) } + if (nodeExternals) { + /** + * https://www.npmjs.com/package/webpack-node-externals + * 这个库扫描node_modules文件夹中的所有 node_modules 名称,并构建一个外部函数,告诉 Webpack 不要捆绑这些模块或它们的任何子模块 + * */ newConfig.externals = [webpackNodeExternals()] } - if (type === "server") { + if (options.miniServer && type === "server") { + /** server 端 去除代码压缩 */ + newConfig.optimization.minimize = false + newConfig.optimization.minimizer = [] + } + + if (options.miniClient && type === "client") { + /** client 端 去除代码压缩 */ newConfig.optimization.minimize = false newConfig.optimization.minimizer = [] } + return newConfig } export default async (env: "development" | "production", options: OptionsProps, isWebpackDevServer: boolean = false) => { - + /** 端口处理 */ const PORT = await choosePort(HOST, DEFAULT_PORT); - + /** 加载自定义配置 */ const overrides = await loaderConf() process.env.PORT = PORT || "3000" process.env.HOST = HOST || "localhost"; - - const { overridesClientWebpack, overridesServerWebpack, overridesWebpack, ...rest } = overrides + const { overridesClientWebpack, overridesServerWebpack, overridesWebpack, overridesCommonWebpack, ...rest } = overrides const configFactory = require(`${webpackConfigPath}`); let configArr: webpack.Configuration[] = [] - /**------------------------ client --------------------- */ + /**------------------------ client 配置 --------------------- */ if (fs.existsSync(overrides.client_path)) { const configClient = configFactory(env); let newConfigClient = configClient + // 控制 client 是否使用 ssr,默认情况下使用 if (!options.original) { - newConfigClient = getWebpackConfig(configClient, "client", overrides, options.clientNodeExternals, options.clientIsChunk, env, isWebpackDevServer) + + newConfigClient = getWebpackConfig(configClient, "client", overrides, options.clientNodeExternals, options.clientIsChunk, env, isWebpackDevServer, options) } if (isWebpackDevServer && !options.original) { // 去除 source-map-loader newConfigClient = removeSourceMapLoader(newConfigClient) } + if (overridesCommonWebpack) { + newConfigClient = overridesCommonWebpack(newConfigClient, env, { ...rest, env }) + } if (overridesClientWebpack) { newConfigClient = overridesClientWebpack(newConfigClient, env, { ...rest, env }) } configArr.push(newConfigClient) } - /**------------------------ server --------------------- */ + /**------------------------ server 配置 --------------------- */ if (fs.existsSync(overrides.server_path)) { + const configServer = configFactory(env); - let newConfigServer = getWebpackConfig(configServer, "server", overrides, options.serverNodeExternals, options.serverIsChunk, env, isWebpackDevServer) + + let newConfigServer = getWebpackConfig(configServer, "server", overrides, options.serverNodeExternals, options.serverIsChunk, env, isWebpackDevServer, options) + newConfigServer.devtool = false newConfigServer.target = "node14" + + /** server 处理 css */ newConfigServer = restDevModuleRuleCss(newConfigServer) - // 去除 source-map-loader + /** 去除 source-map-loader */ newConfigServer = removeSourceMapLoader(newConfigServer) + + if (overridesCommonWebpack) { + + newConfigServer = overridesCommonWebpack(newConfigServer, env, { ...rest, env }) + + } + if (overridesServerWebpack) { + newConfigServer = overridesServerWebpack(newConfigServer, env, { ...rest, env }) + } + configArr.push(newConfigServer) } /**------------------------ other --------------------- */ if (overridesWebpack && typeof overridesWebpack === "function") { + configArr = overridesWebpack(configArr, env, { ...rest, env }) as webpack.Configuration[] + } return { diff --git a/example/basic-plugins/package.json b/example/basic-plugins/package.json index 2278aa8..8d9aa89 100644 --- a/example/basic-plugins/package.json +++ b/example/basic-plugins/package.json @@ -1,6 +1,6 @@ { "name": "@examples/basic-plugins", - "version": "3.1.6", + "version": "3.1.7", "description": "", "private": true, "scripts": { @@ -16,7 +16,7 @@ "react-dom": "17.0.2" }, "devDependencies": { - "@kkt/ssr": "3.1.6", + "@kkt/ssr": "3.1.7", "kkt": "~7.1.5" }, "browserslist": { diff --git a/example/basic-routes-rematch-new/package.json b/example/basic-routes-rematch-new/package.json index 6b24d90..0bef838 100644 --- a/example/basic-routes-rematch-new/package.json +++ b/example/basic-routes-rematch-new/package.json @@ -1,6 +1,6 @@ { "name": "@examples/basic-routes-rematch-new", - "version": "3.1.6", + "version": "3.1.7", "description": "", "private": true, "scripts": { @@ -22,7 +22,7 @@ "serialize-javascript": "6.0.0" }, "devDependencies": { - "@kkt/ssr": "3.1.6", + "@kkt/ssr": "3.1.7", "kkt": "~7.1.5" }, "browserslist": { diff --git a/example/basic-routes/package.json b/example/basic-routes/package.json index 95d4f59..5308012 100644 --- a/example/basic-routes/package.json +++ b/example/basic-routes/package.json @@ -1,6 +1,6 @@ { "name": "@examples/basic-routes", - "version": "3.1.6", + "version": "3.1.7", "description": "", "private": true, "scripts": { @@ -18,7 +18,7 @@ "react-router-dom": "^6.2.2" }, "devDependencies": { - "@kkt/ssr": "3.1.6", + "@kkt/ssr": "3.1.7", "kkt": "~7.1.5" }, "browserslist": { diff --git a/example/basic/package.json b/example/basic/package.json index 7b1251f..45faa87 100644 --- a/example/basic/package.json +++ b/example/basic/package.json @@ -1,6 +1,6 @@ { "name": "@examples/basic", - "version": "3.1.6", + "version": "3.1.7", "description": "", "private": true, "scripts": { @@ -16,7 +16,7 @@ "react-dom": "17.0.2" }, "devDependencies": { - "@kkt/ssr": "3.1.6", + "@kkt/ssr": "3.1.7", "kkt": "~7.1.5" }, "browserslist": { diff --git a/example/react-router-rematch-old/.kktssrrc.js b/example/react-router-rematch-old/.kktssrrc.js index bd98f84..ba7492d 100644 --- a/example/react-router-rematch-old/.kktssrrc.js +++ b/example/react-router-rematch-old/.kktssrrc.js @@ -4,38 +4,35 @@ export default { proxySetup: (app) => ({ path: "./mocker/index.js", }), - overridesWebpack: (confArr, env, options) => { - const arr = [] - confArr.forEach((conf,) => { - const newConfig = pluginLess(conf, { - target: conf.target, - env, - paths: options.paths - }) - arr.push({ - ...newConfig, - module: { - ...newConfig.module, + overridesClientWebpack: (conf, env, options) => { + return { + ...conf, + resolve: { + ...conf.resolve, + fallback: { + "util": require.resolve("util/"), + "crypto": require.resolve("crypto-browserify"), + "stream": require.resolve("stream-browserify"), + "http": require.resolve("stream-http"), + "https": require.resolve("https-browserify"), + "url": require.resolve("url/"), + "zlib": require.resolve("browserify-zlib"), + "tty": require.resolve("tty-browserify"), + "assert": require.resolve("assert/"), + "path": require.resolve("path-browserify"), + "os": require.resolve("os-browserify/browser"), + "buffer": require.resolve("buffer/") }, - resolve: { - ...newConfig.resolve, - fallback: !/node/.test(newConfig.target) && { - "util": require.resolve("util/"), - "crypto": require.resolve("crypto-browserify"), - "stream": require.resolve("stream-browserify"), - "http": require.resolve("stream-http"), - "https": require.resolve("https-browserify"), - "url": require.resolve("url/"), - "zlib": require.resolve("browserify-zlib"), - "tty": require.resolve("tty-browserify"), - "assert": require.resolve("assert/"), - "path": require.resolve("path-browserify"), - "os": require.resolve("os-browserify/browser"), - "buffer": require.resolve("buffer/") - } || {}, - } - }) + } + } + }, + overridesCommonWebpack: (conf, env, options) => { + const newConfig = pluginLess(conf, { + target: conf.target, + env, + paths: options.paths }) - return arr - } + return newConfig + }, + } \ No newline at end of file diff --git a/example/react-router-rematch-old/package.json b/example/react-router-rematch-old/package.json index 1fa0474..b25f883 100644 --- a/example/react-router-rematch-old/package.json +++ b/example/react-router-rematch-old/package.json @@ -1,6 +1,6 @@ { "name": "@examples/basic-routes-rematch-old", - "version": "3.1.6", + "version": "3.1.7", "description": "", "private": true, "scripts": { @@ -15,7 +15,7 @@ "author": "Kenny Wong ", "license": "MIT", "dependencies": { - "@kkt/react-ssr-enhanced": "3.1.6", + "@kkt/react-ssr-enhanced": "3.1.7", "@rematch/core": "2.2.0", "axios": "0.26.0", "cookie-parser": "1.4.3", @@ -31,8 +31,8 @@ "redux": "4.1.2" }, "devDependencies": { - "@kkt/plugin-less": "3.1.6", - "@kkt/ssr": "3.1.6", + "@kkt/plugin-less": "3.1.7", + "@kkt/ssr": "3.1.7", "assert": "2.0.0", "browserify-zlib": "0.2.0", "buffer": "6.0.3", diff --git a/lerna.json b/lerna.json index a61b1cb..53386ea 100644 --- a/lerna.json +++ b/lerna.json @@ -6,7 +6,7 @@ "packages/react-ssr-enhanced", "packages/kkt-plugin-less" ], - "version": "3.1.6", + "version": "3.1.7", "command": { "create": { "license": "MIT" diff --git a/packages/create-kkt-ssr/package.json b/packages/create-kkt-ssr/package.json index 731eac5..ebf6108 100644 --- a/packages/create-kkt-ssr/package.json +++ b/packages/create-kkt-ssr/package.json @@ -1,6 +1,6 @@ { "name": "create-kkt-ssr", - "version": "3.1.6", + "version": "3.1.7", "description": "CLI tool to bootstrap KKT applications with no configuration", "main": "lib/index.js", "bin": { diff --git a/packages/kkt-plugin-less/package.json b/packages/kkt-plugin-less/package.json index b4fa00e..4014e44 100644 --- a/packages/kkt-plugin-less/package.json +++ b/packages/kkt-plugin-less/package.json @@ -1,6 +1,6 @@ { "name": "@kkt/plugin-less", - "version": "3.1.6", + "version": "3.1.7", "description": "Support less.", "main": "lib/index.js", "module": "esm/index.js", diff --git a/packages/react-ssr-enhanced/package.json b/packages/react-ssr-enhanced/package.json index afbe114..c8f095e 100644 --- a/packages/react-ssr-enhanced/package.json +++ b/packages/react-ssr-enhanced/package.json @@ -1,6 +1,6 @@ { "name": "@kkt/react-ssr-enhanced", - "version": "3.1.6", + "version": "3.1.7", "description": "KKT react server side rendering enhancement tool.", "main": "lib/index.js", "module": "esm/index.js",