@tuax/plugin-react
Version:
support react 18
46 lines (39 loc) • 1.62 kB
JavaScript
/**
* react fast refresh loader
* @see https://github.com/facebook/react/issues/16604
* @see https://github.com/pekala/react-refresh-test
* 使用原始代码进行组件注册,如果使用babel等编译过的代码,风险较大,因为不确定用户端的browserlist的配置,代码结构不能预测
* 不能和代码注入放到一个loader里是因为, refresh-loader在代码前面加了代码,导致es6 import 不是在文件的最顶端,会导致babel不能编译
*/
const parser = require('@babel/parser');
const traverse = require('@babel/traverse');
const t = require('@babel/types');
const generate = require('@babel/generator').default;
module.exports = function (source, map, meta) {
const sourceAst = parser.parse(source, {
sourceType: 'module', plugins: [
'jsx',
'flow', // flow 和 typescript 只能二选一,可以改成可配置的
'classProperties',
'decorators-legacy',
],
});
const sourcePath = this.resourcePath;
const comRegister = '';
traverse.default(sourceAst, {
enter (path) {
if (t.isClassDeclaration(path.node, {}) && !!path.node.id && !!path.node.id.name) {
const safeSourcePath = sourcePath.replace(/\\/g, '\\\\');
const comRegistAst = parser.parse(`wglobal.$RefreshReg$(${path.node.id.name}, '${safeSourcePath}_${path.node.id.name}')\n`);
path.insertAfter(comRegistAst.program.body[0]);
}
},
});
const output = generate(sourceAst, {}, source);
source = `
${output.code}
${comRegister}
// $refresh-loader_should_handle_this$
`;
this.callback(null, source, map, meta);
};