「03」打包JSX方法

506 阅读2分钟

前面我们已经实现了jsx方法,现在需要打包jsx,而我们是实现了三个三个方法,分别是jsxjsxDEVReact.createElement,所以对应的我们也需要打包成对应文件分别是:

  • react/jsx-dev-runtime.js(dev环境)
  • react/jsx-runtime.js(prod环境)
  • react/react.js

明确目标

当前我们需要使用rollup进行打包,并且自动生成package.json

实现打包脚本

我们的打包脚本都在scripts

新建scripts/rollup/react.config.js

我们只需要导出一个配置数组即可,inputoutputplugins

export default [
    {
        input: xxx,
        output: xxx,
        plugins: xxx
    }
]

inputoutput我们都需要传入包的路径,显然我们不希望写死,所以需要实现包路径的方法。

目前我们想要的是

  • 传入包名,获得包的路径
  • 传入包名,找到对应包的package.json的位置,并返回package.json序列化配置

新建scripts/rollup/utils.js

我们先定义所有包的路径常量和所有包打包产物路径常量

// 所有包的路径
const pkgPath = path.resolve(__dirname, '../../packages');
// 打包产物路径
const distPath = path.resolve(__dirname, '../../dist/node_modules');

然后来实现获取包路径方法,参数pkgName 包名,isDist 标识是否打包

export function resolvePkgPath(pkgName, isDist) {
	if (isDist) {
		return `${distPath}/${pkgName}`;
	}
	return `${pkgPath}/${pkgName}`;
}

之后来实现获取package.json序列化配置的方法

export function getPackageJSON(pkgName){
    // 包路径
    const path=`${resolvePkgPath(pkgName)}/package.json`
    const str=fs.readFileSync(path,{encoding:'utf-8'})
    return JSON.parse(str)
}

现在我们就可以来配置scripts/rollup/react.config.js的配置了

分别配置react.js产物的出入口,jsx-runtime.jsjsx-dev-runtime.js 产物,当然这远远不够,还需要对TS进行打包,和对ESM进行打包的插件

export default [
	// react
	{
		input: `${pkgPath}/${module}`,
		output: {
			file: `${pkgDistPath}/index.js`,
			name: 'index.js',
			format: 'umd'
		},
		plugins: xxx
		
	},
	// jsx-runtime
	{
		input: `${pkgPath}/src/jsx.ts`,
		output: [
			// jsx-runtime
			{
				file: `${pkgDistPath}/jsx-runtime.js`,
				name: 'jsx-runtime.js',
				format: 'umd'
			},
			// jsx-dev-runtime
			{
				file: `${pkgDistPath}/jsx-dev-runtime.js`,
				name: 'jsx-dev-runtime.js',
				format: 'umd'
			}
		],
	}
];

现在我们需要一个用于解析commonjs的plugin和解析TS的plugin

安装

pnpm i -D -w rollup  rollup-plugin-typescript2 @rollup/plugin-commonjs

添加utils

// 获取所有的公用的plugins
export function getBaseRollupPlugin({ typescript = {} } = {}) {
	return [cjs(), ts(typescript)];
}

配置react.config.js

/**
 * react包的大包配置
 */
import { getPackageJSON, resolvePkgPath, getBaseRollupPlugin } from './utils';
import generatePackageJSON from 'rollup-plugin-generate-package-json';

const { name, module } = getPackageJSON('react');
// react包的路径
const pkgPath = resolvePkgPath(name);
// react产物路径
const pkgDistPath = resolvePkgPath(name, true);

export default [
	// react
	{
		input: `${pkgPath}/${module}`,
		output: {
			file: `${pkgDistPath}/index.js`,
			name: 'index.js',
			format: 'umd'
		},
		plugins: [
			...getBaseRollupPlugin(),
			generatePackageJSON({
				inputFolder: pkgPath,
				outputFolder: pkgDistPath,
				baseContents: ({ name, description, version }) => ({
					name,
					description,
					version,
					main: 'index.js'
				})
			})
		]
	},
	// jsx-runtime
	{
		input: `${pkgPath}/src/jsx.ts`,
		output: [
			// jsx-runtime
			{
				file: `${pkgDistPath}/jsx-runtime.js`,
				name: 'jsx-runtime.js',
				format: 'umd'
			},
			// jsx-dev-runtime
			{
				file: `${pkgDistPath}/jsx-dev-runtime.js`,
				name: 'jsx-dev-runtime.js',
				format: 'umd'
			}
		],
		plugins: getBaseRollupPlugin()
	}
];

最后我们来往根目录下新增命令

"scripts": {
	"build:dev": "rimraf dist && rollup --bundleConfigAsCjs --config scripts/rollup/react.config.js"
},

这里使用了rimraf来在打包前删除dist下的文件,兼容windows,否则可以直接使用rm -rf

pnpm i -D -w rimraf

仅打包三个文件还不够,我们还需要自定义生成dist/package.jsoon

  • 安装插件
pnpm i -D -w rollup-plugin-generate-package-json

目前就完成了react文件的打包。

所有代码:github.com/ohlyf/oh-re…