hel
hel copied to clipboard
已有的react vite项目怎么改造呢
已有vue项目参考这个示例: https://github.com/hel-eco/vue-admin-template-with-hel
react 参考这个
已有react项目接入hel
安装工具包
安装 hel-dev-utils
包
npm i hel-dev-utils
生成子应用描述对象
以执行弹射后的create-react-app
项目模板为例,建议在config
目录下创建一个subApp.js
文件,copy如下内容
const helDevUtils = require('hel-dev-utils');
const pkg = require('../package.json');
const subApp = helDevUtils.createReactSubApp(pkg);
// 若是私服部署,可设定 homePage
// const subApp = helDevUtils.createReactSubApp(pkg, {homePage:'https://xxx.com/yy'});
module.exports = subApp;
替换publicUrlOrPath和buildPath
在config
目录下找到paths
文件,替换掉里面的publicUrlOrPath
和buildPath
定义值
const subApp = require('./subApp');
const publicUrlOrPath = subApp.getPublicPathOrUrl();
const buildPath = subApp.distDir;
替换jsonpFunction
替换config/webpack.config.js
文件里output.jsonpFunction
(或output.chunkLoadingGlobal
)对象下的内容(有则替换,无则新增)
- webpack 4
{
// 其他属性略...
jsonpFunction: subApp.jsonpFnName
}
- webpack 5
webpack 5 已将
jsonpFunction
替换为chunkLoadingGlobal
,所以替换或新增的属性和 webpack 4 有差异
{
// 其他属性略...
chunkLoadingGlobal: subApp.jsonpFnName,
}
设置react为externals
推荐设置react为externals,避免react参与打包,同时也方便后续hel-micro-react
SDK使用其他的远程react模块
替换config/webpack.config.js
文件里module.exports
返回对象的externals
值(有则合并,无则新增)
- 已有自己定义的externals
const subApp = require('./subApp');
module.exports = function (webpackEnv) {
return {
// 其他属性略...
externals: {...yourExternals, ...subApp.externals},
};
}
- 无externals
const subApp = require('./subApp');
module.exports = function (webpackEnv) {
return {
// 其他属性略...
externals: subApp.externals,
};
}
在public/index.html
里引入cdn react
运行时
- ver 18
<script src="https://tnfe.gtimg.com/hel-runtime/level1/18.1.0-react.dev.js"></script>
- ver 17
<script src="https://tnfe.gtimg.com/hel-runtime/level1/17.0.2-react.dev.js"></script>
- ver 16
<script src="https://tnfe.gtimg.com/hel-runtime/level1/16.14.0-react.dev.js"></script>
注:.dev 后缀仅为了本地调试时方便查看详细错误,部署时插件会自动替换为 production 版本,其他版本可联系
fantasticsoul
帮忙发布,此处可根据实际情况可以去掉.dev后缀
暴露共享模块
当前项目有共享给其他项目使用的模块时,可接入此步骤
安装工具包
执行以下npm命令,安装相关包体
npm i hel-lib-proxy
npm i [email protected] rollup@2 rollup-plugin-typescript rollup-plugin-terser shx replace-absolute-path -D
下沉入口文件
将原来的 src/index.js 内容复制到 src/loadApp.js 里,类似此文件,原入口文件index.js
内容改动稍后步骤会提到
新增模块组名描述文件
package.json
里的appGroupName
写上模块组名
新增 src/configs/subApp.ts
(如是js工程,此处创建为subApp.js
),内容如下,确保LIB_NAME
和package.json
里的appGroupName
保持一致
/*
|--------------------------------------------------------------------------
|
| 对应 package.json appGroupName
|
|--------------------------------------------------------------------------
*/
export const LIB_NAME = 'remote-react-comps-tpl';
新增模块暴露目录
新增 src/entrance
目录作为统一暴露模块的出口目录(可参考此文件)
目录下新建两个文件libProperties.ts
(如是js工程,此处创建为libProperties.js
)和libTypes.ts
(注意此文件一定是ts文件)
libProperties.ts
用于暴露共享模块
// 导出模块可按项目实际情况调整,这里仅做示例
import * as comps from 'components';
export default comps;
libTypes.ts
用于导出共享模块类型,并作为rollup打包入口,方便有静态导入和类型提示需求的用户使用npm包来完成此目的,内容如下
import libProperties from './libProperties';
import { exposeLib } from 'hel-lib-proxy';
import { LIB_NAME } from 'configs/subApp';
export type Lib = typeof libProperties;
export const lib = exposeLib<Lib>(LIB_NAME);
/** 如想使用方可在import语句里直接解构出具体的模块,可写为
可参考:https://github.com/hel-eco/hel-tdesign-react/blob/main/src/entrance/libTypes.ts
export cont XX = lib.XX;
export cont YY = lib.YY;
*/
export default lib;
改造入口文件
改造入口文件,做分流控制(可参考此文件)
// import { preFetchLib } from 'hel-micro';
import { libReady, isSubApp } from 'hel-lib-proxy';
import { LIB_NAME } from './configs/subApp';
async function main() {
// 如有其他包依赖,且需要在逻辑里静态导入,可在此处执行预抓取
// await helMicro.preFetchLib('other-lib');
const libProperties = await import('./entrance/libProperties');
// 表示模块已准备就绪,注意此处传递的是 default
libReady(LIB_NAME, libProperties.default);
// 非子应用时(即不是被别的模块触发载入的情况),自己挂载渲染节点,方便本地调试
if (!isSubApp()) {
await import('./loadApp');
}
}
main().catch(console.error);
// avoid isolatedModules warning
export default 'Hel Module Index file';
接入npm构建相关辅助脚本
项目根目录下新建scripts
目录,新增以下脚本meta.js
、check.js
、replaceToRelativePath.js
(可参考此处)
meta.js
用于辅助私有部署时提取hel-meta.json
数据,内容如下:
/*
* 生成 hel-meta.json
*/
const path = require('path');
const process = require('process');
const helDevUtils = require('hel-dev-utils');
const packageJson = require('../package.json');
const subApp = require('../config/subApp');
helDevUtils.extractHelMetaJson({
appHomePage: subApp.getPublicPathOrUrl(),
buildDirFullPath: path.join(__dirname, '../hel_dist'),
packageJson,
platform: subApp.platform,
}).catch((err) => {
console.error(err);
process.exit(-1);
});
check.js
用于校验组名是否一致,内容如下:
const path = require('path');
const helDevUtils = require('hel-dev-utils');
const pkg = require('../package.json');
const fileFullPath = path.join(__dirname, '../src/configs/subApp');
helDevUtils.check(pkg, { fileFullPath, checkEnv: process.env.CHECK_ENV !== '0' });
replaceToRelativePath.js
用于将整个项目的绝对路径替换为相对路径,辅助rollup打包,内容如下
const path = require('path');
const replacePath = require('replace-absolute-path');
(async function () {
const srcDir = process.env.BUNDLE === 'true' ? path.resolve(__dirname, '../lib-js') : path.resolve(__dirname, '../src');
const libDir = process.env.BUNDLE === 'true' ? path.resolve(__dirname, '../lib-js') : path.resolve(__dirname, '../lib');
replacePath({
inputDir: srcDir,
outputDir: libDir,
// includeExts: DEFAULT_EXTS.concat(['.md']),
afterReplaced: () => {
console.log('----------------------------------------------------------------------------------');
console.log(`| all files import statements been transformed to relative path for ${libDir} ^_^ |`);
console.log('----------------------------------------------------------------------------------');
},
});
})().catch((err) => {
console.error(err);
process.exit(-1);
});
引入rollup配置文件
根目录下新增rollup.config.js
文件,内容如下:
:::tip 此步骤为可选项 不需要发包到npm时(即使用方不需要静态导入和类型提示功能时),可以跳过此步骤 :::
import typescript from 'rollup-plugin-typescript';
import { terser } from 'rollup-plugin-terser';
import { cst } from 'hel-dev-utils';
import pkg from './package.json';
const env = process.env.BUILD_ENV || 'umd';
const plugins = [
typescript({
exclude: 'node_modules/**',
typescript: require('typescript'),
}),
];
const env2outputConf = {
es: {
format: 'es',
name: pkg.appGroupName,
file: `${cst.HEL_PROXY_DIR}_es/entry.js`,
},
umd: {
format: 'umd',
name: pkg.appGroupName,
file: `${cst.HEL_PROXY_DIR}/entry.js`,
},
};
const outputObj = env2outputConf[env];
if (process.env.MIN === 'true') {
plugins.push(terser());
const [dirName] = outputObj.file.split('/');
outputObj.file = `${dirName}/entry.min.js`;
}
module.exports = {
input: 'src/entrance/libTypes.ts',
plugins,
output: [
outputObj,
],
};
新增相关构建命令
在package.json
的scripts
节点下引入相关构建命令
"scripts": {
"check": "node ./scripts/check.js",
"build": "npm run build_dist",
"build_dist": "node scripts/build.js",
"build_proxy": "npm run build_proxy_umd && npm run build_proxy_es",
"build_proxy_umd": "tsc & node ./scripts/replaceToRelativePath.js & rollup -c",
"build_proxy_es": "tsc & node ./scripts/replaceToRelativePath.js & cross-env BUILD_ENV=es rollup -c",
"build_meta": "node scripts/meta.js",
"set_home_page": "cross-env-shell HEL_APP_HOME_PAGE=http://127.0.0.1:8080",
"build_cust": "npm run set_home_page \"npm run build_dist && npm run build_meta\"",
"check_name": "node ./scripts/check.js",
"build_priv": "cross-env-shell CHECK_ENV=0 \"npm run check_name && npm run build_dist && npm run build_meta && npm run build_proxy\"",
"build_priv:hint": "work for custom deploy",
"build_helpack": "cross-env-shell CHECK_ENV=0 HEL_APP_HOME_PAGE=http://tnfe.cdn/hel/xxx-name_202202021212 \"npm run check_name && npm run build_dist && npm run build_meta && npm run build_proxy\"",
"build_helpack:hint": "just mock helpack build process to see hel-meta.json result"
}
:::tip build_dist命令 build_dist命令你原来的webpack构建命令即可,相关命令命名可以自行调整 :::
构建与发布npm
执行以下命令
npm run build
npm publish
:::tip npm只发布了源码 npm只发布了源码,运行时代码需要自己发布到相关cdn,如已接入helpack则helpack会自动做相关事宜 :::
这个是要求webpack5的吧? webpack4就搞死人了
这个是要求webpack5的吧? webpack4就搞死人了
不需要webpack 5
有封装的cli命令吗