发布npm之前增加打包工具构建
parent
e9ce2d0b98
commit
69f83b0adc
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(npm install:*)",
|
||||
"Bash(npm run build)",
|
||||
"Bash(wait:*)",
|
||||
"Bash(tree:*)",
|
||||
"Bash(cat:*)",
|
||||
"Bash(git rm:*)",
|
||||
"Bash(git check-ignore:*)"
|
||||
],
|
||||
"deny": [],
|
||||
"ask": []
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,21 @@
|
|||
# 源文件测试目录
|
||||
/src/test/
|
||||
/target/
|
||||
|
||||
# 构建输出(根目录的构建产物)
|
||||
/components/
|
||||
/hooks/
|
||||
/utils/
|
||||
/regular/
|
||||
/enum/
|
||||
/json/
|
||||
/css/
|
||||
|
||||
# IDE
|
||||
.idea
|
||||
|
||||
# 依赖
|
||||
/node_modules
|
||||
*.local
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
# 源文件目录(不要发布)
|
||||
src/
|
||||
rollup.config.js
|
||||
|
||||
# 开发相关文件
|
||||
.eslintrc.cjs
|
||||
.eslintignore
|
||||
|
|
|
|||
|
|
@ -11,4 +11,8 @@ yarn add zy-react-library
|
|||
|
||||
### v1.0.0 (2025-10-22)
|
||||
|
||||
- 🎉 初始版本发布
|
||||
- 🎉 初始版本发布
|
||||
|
||||
### v1.1.2 (2025-12-25)
|
||||
|
||||
- 🎉 优化编译效果
|
||||
13
package.json
13
package.json
|
|
@ -20,6 +20,9 @@
|
|||
"node": ">=18.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "rollup -c",
|
||||
"build:watch": "rollup -c -w",
|
||||
"prepublishOnly": "npm run build",
|
||||
"postinstall": "echo 'Thanks for using our component library!'"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
@ -37,5 +40,15 @@
|
|||
"react": "^18.3.1",
|
||||
"react-pdf": "^10.2.0",
|
||||
"react-signature-canvas": "^1.1.0-alpha.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.28.5",
|
||||
"@babel/preset-react": "^7.28.5",
|
||||
"@rollup/plugin-babel": "^6.1.0",
|
||||
"@rollup/plugin-commonjs": "^29.0.0",
|
||||
"@rollup/plugin-json": "^6.1.0",
|
||||
"@rollup/plugin-node-resolve": "^16.0.3",
|
||||
"glob": "^13.0.0",
|
||||
"rollup": "^4.54.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,288 @@
|
|||
import resolve from '@rollup/plugin-node-resolve';
|
||||
import commonjs from '@rollup/plugin-commonjs';
|
||||
import json from '@rollup/plugin-json';
|
||||
import babel from '@rollup/plugin-babel';
|
||||
import { readFileSync, existsSync } from 'fs';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { glob } from 'glob';
|
||||
|
||||
// 获取当前文件所在目录的绝对路径
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
// 读取 package.json,用于获取依赖列表
|
||||
const pkg = JSON.parse(readFileSync('./package.json', 'utf-8'));
|
||||
|
||||
/**
|
||||
* 收集所有的入口文件
|
||||
*
|
||||
* 遍历指定目录,查找所有 .js 文件作为打包入口
|
||||
* 注意:json 目录被排除,因为 JSON 文件直接复制,不作为入口处理
|
||||
*
|
||||
* @returns {Object} 入口文件对象,格式:{ 'components/Table/index.js': '/absolute/path/Table/index.js' }
|
||||
*/
|
||||
function getEntryFiles() {
|
||||
const entries = {};
|
||||
const baseDir = __dirname;
|
||||
const srcDir = path.join(baseDir, 'src');
|
||||
|
||||
// 定义需要处理的目录(排除json,json文件直接复制不转换)
|
||||
const dirs = ['components', 'hooks', 'utils', 'regular', 'enum'];
|
||||
|
||||
dirs.forEach(dir => {
|
||||
const dirPath = path.join(srcDir, dir);
|
||||
|
||||
if (existsSync(dirPath)) {
|
||||
// 递归查找当前目录下所有 .js 文件
|
||||
const files = glob.sync('**/*.js', {
|
||||
cwd: dirPath, // 在 src/xxx 目录中查找
|
||||
absolute: false // 返回相对路径
|
||||
});
|
||||
|
||||
// 为每个文件创建入口映射
|
||||
files.forEach(file => {
|
||||
// key: 保留源文件的相对路径(包括目录和文件名),如 'components/Table/index.js'
|
||||
// value: src 目录下文件的绝对路径
|
||||
const key = path.join(dir, file);
|
||||
entries[key] = path.join(srcDir, dir, file);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Babel 配置
|
||||
*
|
||||
* 只转换 JSX 语法,不转译 ES6+ 语法
|
||||
* 这样可以保持代码的现代性,减少构建时间
|
||||
*/
|
||||
const babelConfig = {
|
||||
// 将 Babel helpers 捆绑到每个文件中(避免重复引用)
|
||||
babelHelpers: 'bundled',
|
||||
|
||||
// 排除 node_modules 目录,不进行处理
|
||||
exclude: 'node_modules/**',
|
||||
|
||||
// 支持的文件扩展名
|
||||
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
||||
|
||||
// 使用的预设和插件
|
||||
presets: [
|
||||
['@babel/preset-react', {
|
||||
// 使用新的 JSX 转换方式,自动导入 JSX
|
||||
runtime: 'automatic'
|
||||
}]
|
||||
],
|
||||
plugins: []
|
||||
};
|
||||
|
||||
/**
|
||||
* 自定义插件:复制类型声明文件和样式文件
|
||||
*
|
||||
* 功能:
|
||||
* 1. 复制 .d.ts 类型声明文件
|
||||
* 2. 复制 .less/.css 等样式文件(保持原始格式)
|
||||
* 3. 复制 .json 数据文件(保持原始格式)
|
||||
* 4. 复制 css 文件夹
|
||||
*
|
||||
* 注意:所有源文件都在 src/ 目录,构建输出到根目录
|
||||
*/
|
||||
const copyTypesPlugin = () => ({
|
||||
name: 'copy-types',
|
||||
|
||||
// 在生成 bundle 时执行
|
||||
generateBundle() {
|
||||
const srcDir = path.join(__dirname, 'src');
|
||||
const dirs = ['components', 'hooks', 'utils', 'regular', 'enum', 'json'];
|
||||
const this$1 = this;
|
||||
|
||||
// 处理每个目录
|
||||
dirs.forEach(dir => {
|
||||
const dirPath = path.join(srcDir, dir);
|
||||
|
||||
if (existsSync(dirPath)) {
|
||||
// ===== 1. 复制类型声明文件 (.d.ts) =====
|
||||
const dtsFiles = glob.sync('**/*.d.ts', {
|
||||
cwd: dirPath,
|
||||
absolute: true
|
||||
});
|
||||
|
||||
dtsFiles.forEach(file => {
|
||||
const relativePath = path.relative(dirPath, file);
|
||||
const content = readFileSync(file, 'utf-8');
|
||||
|
||||
// 将文件添加到根目录
|
||||
this$1.emitFile({
|
||||
type: 'asset',
|
||||
fileName: path.join(dir, relativePath),
|
||||
source: content
|
||||
});
|
||||
});
|
||||
|
||||
// ===== 2. 复制样式文件 (.less, .css, .scss, .sass) =====
|
||||
const styleFiles = glob.sync('**/*.{less,css,scss,sass}', {
|
||||
cwd: dirPath,
|
||||
absolute: true
|
||||
});
|
||||
|
||||
styleFiles.forEach(file => {
|
||||
const relativePath = path.relative(dirPath, file);
|
||||
const content = readFileSync(file, 'utf-8');
|
||||
|
||||
// 将样式文件添加到根目录,保持原始格式
|
||||
this$1.emitFile({
|
||||
type: 'asset',
|
||||
fileName: path.join(dir, relativePath),
|
||||
source: content
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// ===== 3. 复制 json 文件夹(保持原始格式,不转换) =====
|
||||
const jsonDir = path.join(srcDir, 'json');
|
||||
if (existsSync(jsonDir)) {
|
||||
const jsonFiles = glob.sync('**/*.json', {
|
||||
cwd: jsonDir,
|
||||
absolute: true
|
||||
});
|
||||
|
||||
jsonFiles.forEach(file => {
|
||||
const relativePath = path.relative(jsonDir, file);
|
||||
const content = readFileSync(file, 'utf-8');
|
||||
|
||||
// 将 JSON 文件添加到根目录
|
||||
this$1.emitFile({
|
||||
type: 'asset',
|
||||
fileName: path.join('json', relativePath),
|
||||
source: content
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// ===== 4. 复制 css 文件夹 =====
|
||||
const cssDir = path.join(srcDir, 'css');
|
||||
if (existsSync(cssDir)) {
|
||||
const cssFiles = glob.sync('**/*', {
|
||||
cwd: cssDir,
|
||||
absolute: true,
|
||||
nodir: true // 不包括目录本身
|
||||
});
|
||||
|
||||
cssFiles.forEach(file => {
|
||||
const relativePath = path.relative(cssDir, file);
|
||||
const content = readFileSync(file, 'utf-8');
|
||||
|
||||
this$1.emitFile({
|
||||
type: 'asset',
|
||||
fileName: path.join('css', relativePath),
|
||||
source: content
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Rollup 插件列表
|
||||
*
|
||||
* 按照执行顺序排列:
|
||||
* 1. resolve - 解析模块路径
|
||||
* 2. babel - 转换 JSX
|
||||
* 3. commonjs - 转换 CommonJS 模块
|
||||
* 4. json - 解析 JSON 导入(但被标记为 external,不会实际转换)
|
||||
* 5. copyTypesPlugin - 复制类型和样式文件
|
||||
*/
|
||||
const plugins = [
|
||||
// 模块解析插件 - 解析 node_modules 中的模块
|
||||
resolve({
|
||||
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
||||
browser: true // 浏览器环境优先
|
||||
}),
|
||||
|
||||
// Babel 转换插件 - 只转换 JSX
|
||||
babel(babelConfig),
|
||||
|
||||
// CommonJS 转换插件 - 允许导入 CommonJS 模块
|
||||
commonjs({
|
||||
transformMixedEsModules: true // 转换混合的 ES 模块
|
||||
}),
|
||||
|
||||
// JSON 插件 - 处理 JSON 导入(配合 external 使用)
|
||||
json(),
|
||||
|
||||
// 自定义插件 - 复制类型和样式文件
|
||||
copyTypesPlugin()
|
||||
];
|
||||
|
||||
/**
|
||||
* External 函数
|
||||
*
|
||||
* 判断模块是否应该标记为"外部依赖"
|
||||
* 外部依赖不会被打包进 bundle,而是保留 import 语句
|
||||
*
|
||||
* @param {string} id - 模块标识符
|
||||
* @returns {boolean} - true 表示外部依赖,不打包
|
||||
*/
|
||||
const external = (id) => {
|
||||
// 1. 样式文件标记为外部 -> 保留 import 语句
|
||||
// 原因:样式文件需要消费者项目配置自己的加载器来处理
|
||||
// 保持 Less 变量(如 @{ant-prefix})不被替换
|
||||
if (id.endsWith('.less') || id.endsWith('.css') || id.endsWith('.scss') || id.endsWith('.sass')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 2. JSON 文件标记为外部 -> 直接使用原始 .json 文件
|
||||
// 原因:避免将 JSON 转换成 JS 模块,保持原始格式
|
||||
// 例如:35MB 的 area.json 不会被转换成 56MB 的 area.json.js
|
||||
if (id.endsWith('.json')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 3. npm 依赖包标记为外部 -> 不打包到 bundle 中
|
||||
// 原因:减少 bundle 体积,避免版本冲突,让消费者项目自己管理依赖
|
||||
// 从 package.json 的 dependencies 中读取依赖列表
|
||||
const dependencies = Object.keys(pkg.dependencies || {});
|
||||
return dependencies.some(dep => id === dep || id.startsWith(dep + '/'));
|
||||
};
|
||||
|
||||
/**
|
||||
* 创建 Rollup 配置的辅助函数
|
||||
*
|
||||
* @param {string} outputDir - 输出目录
|
||||
* @param {string} format - 输出格式('esm' 或 'cjs')
|
||||
* @param {Array} plugins - 插件列表
|
||||
* @returns {Object} Rollup 配置对象
|
||||
*/
|
||||
function createConfig(outputDir, format, plugins) {
|
||||
return {
|
||||
// 入口文件对象
|
||||
input: getEntryFiles(),
|
||||
|
||||
// 输出配置
|
||||
output: {
|
||||
dir: outputDir, // 输出目录
|
||||
format: format, // 输出格式:'esm' 或 'cjs'
|
||||
preserveModules: true, // 保留模块结构,不打包成单个文件
|
||||
preserveModulesRoot: './', // 保留模块结构的根目录
|
||||
entryFileNames: '[name]', // 入口文件名:[name] 保留原始文件名(包括 .js 后缀)
|
||||
exports: 'named' // 导出命名导出
|
||||
},
|
||||
|
||||
// 外部依赖判断函数
|
||||
external,
|
||||
|
||||
// 插件列表
|
||||
plugins
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出配置
|
||||
*
|
||||
* 只输出 ESM 格式到根目录(components/, hooks/, utils/ 等)
|
||||
*/
|
||||
export default createConfig('.', 'esm', plugins);
|
||||
|
|
@ -51,11 +51,11 @@ const FormBuilder = (props) => {
|
|||
/>
|
||||
</Row>
|
||||
{showActionButtons && (
|
||||
<>
|
||||
<div style={{ transform: 'scale(1)', margin: '0px -44px' }}>
|
||||
<div style={{ height: "52px" }}></div>
|
||||
<Row
|
||||
gutter={gutter}
|
||||
style={{ textAlign: "center", backgroundColor: "rgb(241, 241, 242)", margin: "0px -44px", padding: "10px 0", position: "fixed", bottom: "0", width: "100%" }}
|
||||
style={{ textAlign: "center", backgroundColor: "rgb(241, 241, 242)", padding: "10px 0", position: "fixed", bottom: "0", width: "100%" }}
|
||||
>
|
||||
<Col span={24} style={{ textAlign: "center" }}>
|
||||
{customActionButtons || (
|
||||
|
|
@ -75,7 +75,7 @@ const FormBuilder = (props) => {
|
|||
)}
|
||||
</Col>
|
||||
</Row>
|
||||
</>
|
||||
</div>
|
||||
)}
|
||||
</Form>
|
||||
</Spin>
|
||||
|
|
@ -36,7 +36,15 @@ const MapSelector = (props) => {
|
|||
// 初始化地图
|
||||
const initMap = async () => {
|
||||
if (!window.BMapGL) {
|
||||
await dynamicLoadJs("https://api.map.baidu.com/api?v=1.0&type=webgl&ak=OElqFYoKiAH8KFtph8ftLKF5NlNrbCUr&callback=initialize");
|
||||
if (window?.base?.loadDynamicResource) {
|
||||
await window.base.loadDynamicResource({
|
||||
url: "https://api.map.baidu.com/api?v=1.0&type=webgl&ak=OElqFYoKiAH8KFtph8ftLKF5NlNrbCUr&callback=initialize",
|
||||
type: "script",
|
||||
});
|
||||
}
|
||||
else {
|
||||
await dynamicLoadJs("https://api.map.baidu.com/api?v=1.0&type=webgl&ak=OElqFYoKiAH8KFtph8ftLKF5NlNrbCUr&callback=initialize");
|
||||
}
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
|
|
@ -26,9 +26,9 @@ function Page(props) {
|
|||
</div>
|
||||
{
|
||||
(isShowAllAction && isShowFooter) && (
|
||||
<>
|
||||
<div style={{ transform: 'scale(1)', margin: '0px -44px' }}>
|
||||
<div style={{ height: "52px" }}></div>
|
||||
<div style={{ textAlign: "center", backgroundColor: "rgb(241, 241, 242)", margin: "0 -20px", padding: "10px 0", position: "fixed", bottom: "0", width: "100%" }}>
|
||||
<div style={{ textAlign: "center", backgroundColor: "rgb(241, 241, 242)", padding: "10px 0", position: "fixed", bottom: "0", width: "100%" }}>
|
||||
{customActionButtons || (
|
||||
<Space>
|
||||
{extraActionButtons}
|
||||
|
|
@ -38,7 +38,7 @@ function Page(props) {
|
|||
</Space>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue