Skip to content

Commit

Permalink
Properly handle cjs-only react shim
Browse files Browse the repository at this point in the history
  • Loading branch information
zerobias committed Jul 13, 2022
1 parent a4a4cb1 commit d9202b7
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 70 deletions.
46 changes: 26 additions & 20 deletions babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const meta = {
isTest: process.env.NODE_ENV === 'test',
isCompat: false,
isEsm: false,
isSolid: false
isSolid: false,
}

const isBrowserstackDomTest = !!process.env.DOM
Expand Down Expand Up @@ -71,6 +71,20 @@ const aliases = {
test: null,
default: resolveFromSources('../npm/effector'),
},
'^use-sync-external-store/shim/with-selector$': {
esm: 'use-sync-external-store/shim/with-selector.js',
compat: 'use-sync-external-store/shim/with-selector.js',
build: 'use-sync-external-store/shim/with-selector.js',
test: null,
default: null,
},
'^use-sync-external-store/shim$': {
esm: 'use-sync-external-store/shim/index.js',
compat: 'use-sync-external-store/shim/index.js',
build: 'use-sync-external-store/shim/index.js',
test: null,
default: null,
},
}

const babelPlugin = resolvePath(__dirname, 'src', 'babel', 'babel-plugin.js')
Expand All @@ -84,7 +98,9 @@ const locationPlugin = resolvePath(

const babelConfig = {
presets(meta) {
const jsxPreset = meta.isSolid ? ['babel-preset-solid'] : ['@babel/preset-react', {useBuiltIns: true}]
const jsxPreset = meta.isSolid
? ['babel-preset-solid']
: ['@babel/preset-react', {useBuiltIns: true}]

return [
jsxPreset,
Expand Down Expand Up @@ -127,27 +143,17 @@ const babelConfig = {
},
],
]
function addSrcPlugin(condition, fileName) {
if (!condition) return
const pluginPath = resolvePath(__dirname, 'src', 'babel', fileName)
result.unshift(pluginPath)
}
if (meta.isTest) {
result.push('@babel/plugin-transform-modules-commonjs')
}
if (meta.isBuild) {
const constToLetPlugin = resolvePath(
__dirname,
'src',
'babel',
'constToLet.js',
)
result.unshift(constToLetPlugin)
}
if (meta.replaceVueReactivity) {
const replaceVuePlugin = resolvePath(
__dirname,
'src',
'babel',
'vueImports.js',
)
result.unshift(replaceVuePlugin)
}
addSrcPlugin(meta.isBuild, 'constToLet.js')
addSrcPlugin(meta.replaceVueReactivity, 'vueImports.js')
addSrcPlugin(meta.replaceReactShim, 'reactShimImports.js')
return result
},
overrides: [
Expand Down
43 changes: 43 additions & 0 deletions src/babel/defineCjsReplacements.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* @param {import('@babel/core').types} t
* @param {Array<{pkg: string; val: string}>} replacements
*/
function defineReplacements(t, replacements) {
const packages = replacements.map(({pkg}) => pkg)
return (path, ctx) => {
const node = path.node
if (!packages.includes(node.source.value)) return
const programPath = path.find(path => path.isProgram())
if (!ctx.effCjs_importMap) ctx.effCjs_importMap = new Set()
const {pkg, val} = replacements[packages.indexOf(node.source.value)]
const importMap = ctx.effCjs_importMap
if (!importMap.has(pkg)) {
importMap.add(pkg)
programPath.node.body.unshift(
t.importDeclaration(
[t.importDefaultSpecifier(t.identifier(val))],
t.stringLiteral(pkg),
),
)
}
const imports = []
for (let i = 0; i < node.specifiers.length; i++) {
const specifier = node.specifiers[i]
if (t.isImportDefaultSpecifier(specifier)) return
if (!t.isImportSpecifier(specifier)) continue
imports.push(
t.objectProperty(
t.identifier(specifier.imported.name),
t.identifier(specifier.local.name),
),
)
}
path.replaceWith(
t.VariableDeclaration('const', [
t.VariableDeclarator(t.objectPattern(imports), t.identifier(val)),
]),
)
}
}

module.exports.defineReplacements = defineReplacements
30 changes: 30 additions & 0 deletions src/babel/reactShimImports.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const {defineReplacements} = require('./defineCjsReplacements')

module.exports = function (babel) {
const replaceImports = defineReplacements(babel.types, [
{
pkg: 'use-sync-external-store/shim/index.js',
val: 'shimJs',
},
{
pkg: 'use-sync-external-store/shim/with-selector.js',
val: 'shimSelectorJs',
},
{
pkg: 'use-sync-external-store/shim',
val: 'shim',
},
{
pkg: 'use-sync-external-store/shim/with-selector',
val: 'shimSelector',
},
])
return {
name: 'react-shim-imports',
visitor: {
ImportDeclaration(path) {
replaceImports(path, this)
},
},
}
}
44 changes: 4 additions & 40 deletions src/babel/vueImports.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,7 @@
module.exports = function(babel) {
const t = babel.types
function defineReplacements(replacements) {
const packages = replacements.map(({pkg}) => pkg)
return (path, ctx) => {
const node = path.node
if (!packages.includes(node.source.value)) return
const programPath = path.find(path => path.isProgram())
if (!ctx.effVue_importMap) ctx.effVue_importMap = new Set()
const {pkg, val} = replacements[packages.indexOf(node.source.value)]
const importMap = ctx.effVue_importMap
if (!importMap.has(pkg)) {
importMap.add(pkg)
programPath.node.body.unshift(
t.importDeclaration(
[t.importDefaultSpecifier(t.identifier(val))],
t.stringLiteral(pkg),
),
)
}
const imports = []
for (let i = 0; i < node.specifiers.length; i++) {
const specifier = node.specifiers[i]
if (t.isImportDefaultSpecifier(specifier)) return
if (!t.isImportSpecifier(specifier)) continue
imports.push(
t.objectProperty(
t.identifier(specifier.imported.name),
t.identifier(specifier.local.name),
),
)
}
path.replaceWith(
t.VariableDeclaration('const', [
t.VariableDeclarator(t.objectPattern(imports), t.identifier(val)),
]),
)
}
}
const replaceImports = defineReplacements([
const {defineReplacements} = require('./defineCjsReplacements')

module.exports = function (babel) {
const replaceImports = defineReplacements(babel.types, [
{
pkg: '@vue/reactivity',
val: 'reactivity',
Expand Down
39 changes: 29 additions & 10 deletions tools/builder/rollup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,19 @@ const externals = [
'react',
'use-sync-external-store/shim',
'use-sync-external-store/shim/with-selector',
'solid-js'
'use-sync-external-store/shim/index.js',
'use-sync-external-store/shim/with-selector.js',
'solid-js',
]

const getPlugins = (
name: string,
{isEsm = false, replaceVueReactivity = false, replaceVueNext = false} = {},
{
isEsm = false,
replaceVueReactivity = false,
replaceReactShim = false,
replaceVueNext = false,
} = {},
) => ({
babel: isEsm
? babel({
Expand All @@ -81,6 +88,7 @@ const getPlugins = (
isEsm: true,
replaceVueReactivity,
replaceVueNext,
replaceReactShim,
}),
})
: babel({
Expand All @@ -96,6 +104,7 @@ const getPlugins = (
isEsm: false,
replaceVueReactivity,
replaceVueNext,
replaceReactShim: false,
}),
}),
commonjs: commonjs({extensions}),
Expand Down Expand Up @@ -205,6 +214,7 @@ export async function rollupEffectorReact() {
es: dir(`npm/${name}/${name}.mjs`),
},
inputExtension: 'ts',
replaceReactShim: true,
}),
createSSR({
file: {
Expand All @@ -219,6 +229,9 @@ export async function rollupEffectorReact() {
globals: {
effector: 'effector',
react: 'React',
'use-sync-external-store/shim/index.js': 'useSyncExternalStoreShim',
'use-sync-external-store/shim/with-selector.js':
'useSyncExternalStoreWithSelectorShim',
},
extension: 'ts',
}),
Expand All @@ -240,10 +253,15 @@ export async function rollupEffectorReact() {
},
input: 'ssr',
inputExtension: 'ts',
replaceReactShim: true,
}),
])
async function runBuild(file: string, format: 'cjs' | 'es') {
const plugins = getPlugins(name, {isEsm: format === 'es'})
const isEsm = format === 'es'
const plugins = getPlugins(name, {
isEsm,
replaceReactShim: isEsm,
})
const pluginList = [
plugins.resolve,
plugins.json,
Expand All @@ -266,7 +284,7 @@ export async function rollupEffectorReact() {
name,
sourcemap: true,
sourcemapPathTransform: getSourcemapPathTransform(name),
externalLiveBindings: format === 'es',
externalLiveBindings: isEsm,
})
}
}
Expand Down Expand Up @@ -298,18 +316,15 @@ export async function rollupEffectorSolid() {
'solid-js': 'SolidJS',
},
extension: 'ts',
})
}),
])

async function createSSR({
file: {cjs, es},
file: {cjs, es},
}: {
file: {cjs: string; es: string}
}) {
await Promise.all([
runBuild(cjs, 'cjs'),
runBuild(es, 'es'),
])
await Promise.all([runBuild(cjs, 'cjs'), runBuild(es, 'es')])
async function runBuild(file: string, format: 'cjs' | 'es') {
const plugins = getPlugins(name, {isEsm: format === 'es'})
const pluginList = [
Expand Down Expand Up @@ -524,16 +539,19 @@ async function createEsCjs(
input = 'index',
inputExtension = 'js',
replaceVueReactivity = false,
replaceReactShim = false,
}: {
file: {es?: string; cjs: string}
renderModuleGraph?: boolean
input?: string
inputExtension?: string
replaceVueReactivity?: boolean
replaceReactShim?: boolean
},
) {
const pluginsCjs = getPlugins(input === 'index' ? name : input, {
replaceVueNext: true,
replaceReactShim: false,
})
const pluginListCjs = [
pluginsCjs.resolve,
Expand All @@ -548,6 +566,7 @@ async function createEsCjs(
isEsm: true,
replaceVueReactivity,
replaceVueNext: true,
replaceReactShim,
})
const pluginListEsm = [
pluginsEsm.resolve,
Expand Down

0 comments on commit d9202b7

Please sign in to comment.