Skip to content

Commit

Permalink
feat(react-vite): plugin-react support vite compiler
Browse files Browse the repository at this point in the history
  • Loading branch information
innocces committed Jul 25, 2024
1 parent 6a1b188 commit 4fd3e69
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 57 deletions.
69 changes: 12 additions & 57 deletions packages/plugin-react/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,65 +1,20 @@
import { chalk } from '@tarojs/helper';
import { IPluginContext } from '@tarojs/service';

// 同时兼容一下 preact 和 nerv
const reactLike = ['preact', 'nerv'];
const supportFrameworks = ['react', ...reactLike];
import { modifyViteConfig } from './runtime/modifyViteConfig';
import { modifyWebpackChain } from './runtime/modifyWebpackChain';

import { getReactPath } from './runtime/shared';
import { supportFrameworks } from './runtime/constant';

// 同时兼容一下 preact 和 nerv
export default (ctx: IPluginContext) => {
const { framework } = ctx.initialConfig;
if ((framework && !supportFrameworks.includes(framework)) || !getReactPath(framework))
if (
(framework && !supportFrameworks.includes(framework)) ||
!getReactPath(framework)
)
return;

ctx.modifyWebpackChain(({ chain, webpack }) => {
setDefinePlugin(chain, webpack);
console.log(
chalk.blue(
`✨ 逮到一个使用taro-hooks的小可爱~ \n 当前使用的框架是: ${framework}`,
),
);

chain.resolve.alias.set('@taro-hooks/core', getRealRuntimePath());

// 检查一下除 react 的框架是否包含了对应的 alias. 不然 runtime 会报错
if (reactLike.includes(framework!) && !chain.resolve.alias.get('react')) {
chain.resolve.alias.set('react', framework!);
}
});
modifyWebpackChain(ctx);
modifyViteConfig(ctx);
};

function setDefinePlugin(chain: any, webpack: any) {
chain.plugin('defined').use(webpack.DefinePlugin, [
{
// fix process is not defined in 3.5.x webpackv5 mode!
__TARO_HOOKS_REACT__: JSON.stringify(true),
__TARO_HOOKS_VUE__: JSON.stringify(false),
TARO_ENV: JSON.stringify(process.env.TARO_ENV?.toLocaleUpperCase()),
},
]);
}

function getNumberVersion(): number {
try {
const pkgPath = require.resolve('@tarojs/taro/package.json', {
paths: [process.cwd()],
});
return require(pkgPath).version?.replace(/\./gi, '');
} catch (e) {
return Infinity;
}
}

function getRealRuntimePath(): string {
return `@taro-hooks/plugin-react/dist/runtime`;
}

export function getReactPath(framework = 'react'): string {
try {
return require.resolve(framework, {
paths: [process.cwd()],
});
} catch (error) {
console.log(chalk.yellow(`找不到 ${framework}. 请先安装。`));
process.exit(1);
}
}
4 changes: 4 additions & 0 deletions packages/plugin-react/src/runtime/constant.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// 同时兼容一下 preact 和 nerv
export const reactLike = ['preact', 'nerv'];

export const supportFrameworks = ['react', ...reactLike];
67 changes: 67 additions & 0 deletions packages/plugin-react/src/runtime/modifyViteConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { IPluginContext } from '@tarojs/service';
import { chalk } from '@tarojs/helper';
import { reactLike } from './constant';
import { getRealRuntimePath, isVersion4, getDefine } from './shared';

export function modifyViteConfig(ctx: IPluginContext) {
const { framework } = ctx.initialConfig;

if (isVersion4() && 'modifyViteConfig' in ctx) {
ctx.modifyViteConfig(({ viteConfig }) => {
const taroHooksVitePlugins = [setDefinePlugin(), setAlias(framework)];
console.log(
chalk.blue(
`✨ 逮到一个使用taro-hooks的小可爱~ \n 当前使用的框架是: ${framework}`,
),
);

viteConfig.plugins.push(...taroHooksVitePlugins);
});
}
}

function setDefinePlugin() {
return {
name: '@taro-hooks/plugin-react:define',
config: () => {
return {
define: {
...getDefine(),
},
};
},
};
}

function setAlias(framework) {
return {
name: '@taro-hooks/plugin-react:alias',
enforce: 'pre',
config: (userConfig) => {
const alias: Record<string, string>[] = [
{ find: '@taro-hooks/core', replacement: getRealRuntimePath() },
];
const userAlias = userConfig.resolve?.alias;
let aliasReact = true;
if (Array.isArray(userAlias)) {
aliasReact = userAlias.find((v) => v.find === 'react');
} else if (
Object.prototype.toString.call(userAlias) === '[object Object]'
) {
aliasReact = 'react' in userAlias;
}
// 检查一下除 react 的框架是否包含了对应的 alias. 不然 runtime 会报错
if (reactLike.includes(framework!) && !aliasReact) {
alias.push({
find: 'react',
replacement: framework,
});
}
return {
resolve: {
alias,
},
};
},
};
}
27 changes: 27 additions & 0 deletions packages/plugin-react/src/runtime/modifyWebpackChain.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { IPluginContext } from '@tarojs/service';
import { chalk } from '@tarojs/helper';
import { reactLike } from './constant';
import { getRealRuntimePath, getDefine } from './shared';

export function modifyWebpackChain(ctx: IPluginContext) {
const { framework } = ctx.initialConfig;
ctx.modifyWebpackChain(({ chain, webpack }) => {
setDefinePlugin(chain, webpack);
console.log(
chalk.blue(
`✨ 逮到一个使用taro-hooks的小可爱~ \n 当前使用的框架是: ${framework}`,
),
);

chain.resolve.alias.set('@taro-hooks/core', getRealRuntimePath());

// 检查一下除 react 的框架是否包含了对应的 alias. 不然 runtime 会报错
if (reactLike.includes(framework!) && !chain.resolve.alias.get('react')) {
chain.resolve.alias.set('react', framework!);
}
});
}

function setDefinePlugin(chain: any, webpack: any) {
chain.plugin('defined').use(webpack.DefinePlugin, [getDefine()]);
}
40 changes: 40 additions & 0 deletions packages/plugin-react/src/runtime/shared.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { chalk } from '@tarojs/helper';

export function getNumberVersion(): number {
try {
const pkgPath = require.resolve('@tarojs/taro/package.json', {
paths: [process.cwd()],
});
return require(pkgPath).version?.replace(/\./gi, '');
} catch (e) {
return Infinity;
}
}

export function isVersion4() {
return String(getNumberVersion()).startsWith('4');
}

export function getRealRuntimePath(): string {
return `@taro-hooks/plugin-react/dist/runtime`;
}

export function getReactPath(framework = 'react'): string {
try {
return require.resolve(framework, {
paths: [process.cwd()],
});
} catch (error) {
console.log(chalk.yellow(`找不到 ${framework}. 请先安装。`));
process.exit(1);
}
}

export function getDefine() {
return {
// fix process is not defined in 3.5.x webpackv5 mode!
__TARO_HOOKS_REACT__: JSON.stringify(true),
__TARO_HOOKS_VUE__: JSON.stringify(false),
TARO_ENV: JSON.stringify(process.env.TARO_ENV?.toLocaleUpperCase()),
};
}

0 comments on commit 4fd3e69

Please sign in to comment.