Skip to content

Commit

Permalink
feat(@kkt/ssr):新增proxySetup参数,修复css名称问题 & 修复页面二次刷新问题 (#21)
Browse files Browse the repository at this point in the history
feat(@kkt/ssr):新增proxySetup参数,修复css名称问题
fix(@kkt/react-ssr-enhanced): 修复页面二次刷新问题 (#21)
  • Loading branch information
SunLxy authored Mar 21, 2022
1 parent f2e0016 commit 7ebe976
Show file tree
Hide file tree
Showing 30 changed files with 261 additions and 84 deletions.
15 changes: 15 additions & 0 deletions core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,21 @@ export default {
}
```

**proxySetup**

Reference [mocker-api](https://github.com/jaywcjlove/mocker-api)

```js
export default {
proxySetup: (app) => ({
path: "./mocker/index.js",
options:{
changeHost: true,
}
}),
}
```

**Rewrite watchOptions**

```js
Expand Down
8 changes: 6 additions & 2 deletions core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@kkt/ssr",
"version": "3.1.3",
"version": "3.1.4",
"description": "",
"license": "MIT",
"main": "lib/index.js",
Expand All @@ -26,12 +26,16 @@
"@types/webpack-node-externals": "^2.5.3"
},
"dependencies": {
"nodemon-webpack-plugin": "^4.7.1",
"@babel/core": "^7.17.8",
"@babel/runtime": "^7.17.8",
"css-loader": "^6.7.1",
"kkt": "~7.1.5",
"mini-css-extract-plugin": "2.6.0",
"mocker-api": "^2.9.5",
"react-scripts": "^5.0.0",
"webpack-manifest-plugin": "^5.0.0",
"webpack-node-externals": "^3.0.0",
"webpackbar": "^5.0.2"
}
}
}
15 changes: 13 additions & 2 deletions core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ process.env.FAST_REFRESH = 'false';
process.env.BUILD_PATH = "dist"



import minimist from 'minimist';
import { BuildArgs } from 'kkt';

function help() {
const { version } = require('../package.json');
console.log('\n Usage: \x1b[34;1mkkt-ssr\x1b[0m [build|watch] [--help|h]');
console.log('\n Usage: \x1b[34;1mkkt-ssr\x1b[0m [build|watch|start] [--help|h]');
console.log('\n Displays help information.');
console.log('\n Options:\n');
console.log(' --version, -v ', 'Show version number');
Expand All @@ -23,6 +22,7 @@ function help() {
console.log('\n Example:\n');
console.log(' $ \x1b[35mkkt-ssr\x1b[0m build');
console.log(' $ \x1b[35mkkt-ssr\x1b[0m watch');
console.log(' $ \x1b[35mkkt-ssr\x1b[0m start');
console.log(' $ \x1b[35mkkt-ssr\x1b[0m build --s-ne');
console.log(' $ \x1b[35mkkt-ssr\x1b[0m watch --s-ne');
console.log(' $ \x1b[35mkkt-ssr\x1b[0m build --s-st');
Expand Down Expand Up @@ -102,6 +102,17 @@ interface SSRNCCArgs extends BuildArgs {
clientIsChunk,
serverIsChunk
})
} else if (scriptName === 'start') {
process.env.BABEL_ENV = 'development';
process.env.NODE_ENV = 'development';

const start = await import("./script/start")
await start.default({
clientNodeExternals,
serverNodeExternals,
clientIsChunk,
serverIsChunk
})
}
} catch (error) {
console.log('\x1b[31m KKT:SSR:ERROR:\x1b[0m', error);
Expand Down
29 changes: 23 additions & 6 deletions core/src/overrides/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@

import fs from 'fs';
import { resolveModule, resolveApp, Paths } from "./pathUtils"

import webpack from "webpack"
import { restENV } from "./env"
import paths from "./path"
import { overridePaths } from 'kkt/lib/overrides/paths';
import { Application } from 'express';

import { MockerOption } from "mocker-api"

const tsOptions = {
compilerOptions: {
Expand Down Expand Up @@ -52,7 +56,11 @@ export interface OverridesProps {
/** 输出文件地址 */
output_path?: string;
/** watch 配置 */
watchOptions?: webpack.Configuration["watchOptions"]
watchOptions?: webpack.Configuration["watchOptions"];
proxySetup?: (app: Application) => {
path: string | string[],
options?: MockerOption
}
}

let overrides: OverridesProps = {
Expand All @@ -65,12 +73,16 @@ let overrides: OverridesProps = {

// paths 地址
paths: {},
// 最终自定义配置设置
// 自定义 client 配置设置
overridesClientWebpack: undefined,
// 自定义 server 配置设置
overridesServerWebpack: undefined,
// 最终自定义配置设置
overridesWebpack: undefined,
watchOptions: {}

// 监听配置
watchOptions: {},
// 代理配置
proxySetup: undefined
};

export async function loaderConf(): Promise<OverridesProps> {
Expand All @@ -94,12 +106,17 @@ export async function loaderConf(): Promise<OverridesProps> {

// 重写环境变量
restENV(overrides)

// 重写 paths 值
const path = paths(overrides)
if (!fs.existsSync(path.appIndexJs)) {
path.appIndexJs = overrides.client_path
}
overrides.paths = path
// 覆盖配置 里面的地址
overridePaths(undefined, { ...(path as unknown as Record<string, string>) });

overridePaths(undefined, {
...(path as unknown as Record<string, string>)
});
return overrides;
} catch (error) {
const message = error && error.message ? error.message : '';
Expand Down
9 changes: 8 additions & 1 deletion core/src/overrides/pathUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,22 @@ export type Paths = {
moduleFileExtensions?: string[]
};


export const appDirectory = fs.realpathSync(process.cwd());

export const resolveApp = (relativePath: string) => path.resolve(appDirectory, relativePath);

export const reactScripts = path.join(require.resolve('react-scripts/package.json'), '..');

export const paths: Paths = require(`${reactScripts}/config/paths`);

export const moduleFileExtensions: string[] = paths.moduleFileExtensions || [];

export const devServerConfigPath = `${reactScripts}/config/webpackDevServer.config`

export const webpackConfigPath = `${reactScripts}/config/webpack.config`

export const reactDevUtils = path.join(require.resolve('react-dev-utils/package.json'), '..');

// Resolve file paths in the same order as webpack
export const resolveModule = (resolveFn: { (relativePath: string): string; (arg0: string): fs.PathLike; }, filePath: string) => {
const extension = moduleFileExtensions.find(extension =>
Expand Down
3 changes: 2 additions & 1 deletion core/src/overrides/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import path from "path"
import { Paths } from "./pathUtils"
import webpack from "webpack"
import MiniCssExtractPlugin from 'mini-css-extract-plugin';

const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent');

// style files regexes
const cssRegex = /\.css$/;
Expand Down Expand Up @@ -145,6 +145,7 @@ export const getModuleCSSRules = (rules: (webpack.RuleSetRule | '...')[], should
sourceMap: shouldUseSourceMap,
modules: {
mode,
getLocalIdent: getCSSModuleLocalIdent,
exportOnlyLocals: true
},
});
Expand Down
41 changes: 41 additions & 0 deletions core/src/script/start.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@


import createCompiler from "./utils"
import { OptionsProps } from "../interface"
import { webpackConfigPath, reactScripts, reactDevUtils } from "./../overrides/pathUtils"
import overridesDevServer from "./utils/overridesDevServer"
const { choosePort } = require('react-dev-utils/WebpackDevServerUtils');

// Tools like Cloud9 rely on this.
const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000;
const HOST = process.env.HOST || 'localhost';

export default async (options: OptionsProps) => {

const PORT = await choosePort(HOST, DEFAULT_PORT);
process.env.PORT = PORT
process.env.HOST = HOST;

try {
const { overrides, config } = await createCompiler("development", options, true)
const openBrowserPath = `${reactDevUtils}/openBrowser`;

require(openBrowserPath);
// override config in memory
require.cache[require.resolve(openBrowserPath)].exports = () => { };

require.cache[require.resolve(webpackConfigPath)].exports = (env: string) => config;

await overridesDevServer(overrides)

require(`${reactScripts}/scripts/start`);

}
catch (error) {
const message = error && error.message ? error.message : '';
console.log('\x1b[31;1m KKT-SSR:START:ERROR: \x1b[0m\n', error);
new Error(`KKT-SSR:START:ERROR: \n ${message}`);
process.exit(1);
}

}
35 changes: 26 additions & 9 deletions core/src/script/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// 根据 kkt 写法 重置 create-react-app 中的 react-script配置
import { reactScripts } from "../../overrides/pathUtils"
import { reactScripts, webpackConfigPath } from "../../overrides/pathUtils"
import webpackNodeExternals from "webpack-node-externals"
import webpack from "webpack"
import { OptionsProps } from "../../interface"
import fs from 'fs';
import nodemonWebpackPlugin from "nodemon-webpack-plugin"

import { loaderConf, OverridesProps } from "./../../overrides"

Expand All @@ -19,7 +20,7 @@ import {
// 引入环境变量
require(`${reactScripts}/config/env`);

const getWebpackConfig = (newConfig: webpack.Configuration, type: "server" | "client", overrides: OverridesProps, nodeExternals: boolean, split: boolean, env: "development" | "production") => {
const getWebpackConfig = (newConfig: webpack.Configuration, type: "server" | "client", overrides: OverridesProps, nodeExternals: boolean, split: boolean, env: "development" | "production", isWebpackDevServer: boolean) => {
newConfig.entry = overrides[`${type}_path`]
newConfig = getWbpackBarPlugins(newConfig, {
name: type,
Expand All @@ -30,18 +31,35 @@ const getWebpackConfig = (newConfig: webpack.Configuration, type: "server" | "cl
}

if (type === "server") {
out.library = { type: "commonjs" }
out.library = { type: "commonjs2" }
}

const HOST = process.env.HOST || 'localhost'
const PORT = process.env.PORT || 3000

newConfig = restOutPut(newConfig, out)
newConfig = restWebpackManifestPlugin(newConfig, overrides.paths, type)
newConfig = clearHtmlTemp(newConfig)
newConfig.module.exprContextCritical = false;
newConfig.plugins.push(
new webpack.DefinePlugin({
OUTPUT_PUBLIC_PATH: JSON.stringify(overrides.output_path),
HOST: JSON.stringify(HOST),
PORT: JSON.stringify(PORT)
}),
)
if (isWebpackDevServer && type === "server") {
newConfig.plugins.push(
new nodemonWebpackPlugin({
script: `${out.path}/${out.filename}`,
watch: [`${out.path}`]
})
)
}

if (isWebpackDevServer) {
newConfig.output.publicPath = `http://${HOST}:${PORT}/`
}

if (!split) {
newConfig.plugins.push(new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 }))
Expand All @@ -53,19 +71,19 @@ const getWebpackConfig = (newConfig: webpack.Configuration, type: "server" | "cl
return newConfig
}

export default async (env: "development" | "production", options: OptionsProps) => {
export default async (env: "development" | "production", options: OptionsProps, isWebpackDevServer: boolean = false) => {
const overrides = await loaderConf()

const { overridesClientWebpack, overridesServerWebpack, overridesWebpack, ...rest } = overrides

const configFactory = require(`${reactScripts}/config/webpack.config`);
const configFactory = require(`${webpackConfigPath}`);

let configArr: webpack.Configuration[] = []

/**------------------------ client --------------------- */
if (fs.existsSync(overrides.client_path)) {
const configClient = configFactory(env);
let newConfigClient = getWebpackConfig(configClient, "client", overrides, options.clientNodeExternals, options.clientIsChunk, env)
let newConfigClient = getWebpackConfig(configClient, "client", overrides, options.clientNodeExternals, options.clientIsChunk, env, isWebpackDevServer)
newConfigClient = addMiniCssExtractPlugin(newConfigClient)
if (overridesClientWebpack) {
newConfigClient = overridesClientWebpack(newConfigClient, env, { ...rest, env })
Expand All @@ -76,7 +94,7 @@ export default async (env: "development" | "production", options: OptionsProps)
/**------------------------ server --------------------- */
if (fs.existsSync(overrides.server_path)) {
const configServer = configFactory(env);
let newConfigServer = getWebpackConfig(configServer, "server", overrides, options.serverNodeExternals, options.serverIsChunk, env)
let newConfigServer = getWebpackConfig(configServer, "server", overrides, options.serverNodeExternals, options.serverIsChunk, env, isWebpackDevServer)
newConfigServer.devtool = false
newConfigServer.target = "node14"
newConfigServer = restDevModuleRuleCss(newConfigServer)
Expand All @@ -91,9 +109,8 @@ export default async (env: "development" | "production", options: OptionsProps)
configArr = overridesWebpack(configArr, env, { ...rest, env }) as webpack.Configuration[]
}

const compiler = webpack(configArr);
return {
compiler,
compiler: isWebpackDevServer ? undefined : webpack(configArr),
config: configArr,
overrides
}
Expand Down
Loading

0 comments on commit 7ebe976

Please sign in to comment.