diff --git a/.gitignore b/.gitignore index 75af7cca..d32b558d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ .cache/ .DS_Store node_modules/ +/index.cjs +/index.mjs /lib/ /react/ /tests/~partytown/ diff --git a/package.json b/package.json index 69344acc..7aac6199 100644 --- a/package.json +++ b/package.json @@ -3,15 +3,23 @@ "version": "0.0.3", "description": "Relocate resource intensive 3rd-party scripts off of the main thread and into a web worker.", "license": "MIT", + "main": "./index.cjs", + "module": "./index.mjs", "exports": { "./react": { + "import": "./react/index.mjs", + "require": "./react/index.cjs" + }, + ".": { "import": "./index.mjs", "require": "./index.cjs" } }, "files": [ "/lib/", - "/react/" + "/react/", + "index.cjs", + "index.mjs" ], "scripts": { "build": "tsc && rollup -c", diff --git a/rollup.config.js b/rollup.config.js index 7b1be6f0..bb0e06c3 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -21,8 +21,8 @@ export default async function (cmdArgs) { const srcDir = join(rootDir, 'src'); const srcLibDir = join(srcDir, 'lib'); const srcReactDir = join(srcDir, 'react'); - const buildDir = join(rootDir, 'lib'); const testsDir = join(rootDir, 'tests'); + const libBuildDir = join(rootDir, 'lib'); const testsBuildDir = join(testsDir, '~partytown'); const reactBuildDir = join(rootDir, 'react'); const cacheDir = join(rootDir, '.cache'); @@ -64,7 +64,7 @@ export default async function (cmdArgs) { }; if (!isDev) { - await emptyDir(buildDir); + await emptyDir(libBuildDir); await emptyDir(reactBuildDir); await emptyDir(testsBuildDir); await emptyDir(join(testsDir, 'videos')); @@ -99,7 +99,7 @@ export default async function (cmdArgs) { const webWorkerCode = generated.output[0].code; if (debug) { - await writeFile(join(buildDir, `partytown-ww.debug.js`), webWorkerCode); + await writeFile(join(libBuildDir, `partytown-ww.debug.js`), webWorkerCode); } else { await writeFile(join(cacheDir, `partytown-ww.js`), webWorkerCode); } @@ -150,7 +150,7 @@ export default async function (cmdArgs) { const sandboxJsCode = generated.output[0].code; let sandboxHtml; if (debug) { - await writeFile(join(buildDir, `partytown-sandbox.debug.js`), sandboxJsCode); + await writeFile(join(libBuildDir, `partytown-sandbox.debug.js`), sandboxJsCode); sandboxHtml = ``; await writeFile(join(cacheDir, `partytown-sandbox.debug.html`), sandboxHtml); @@ -164,7 +164,7 @@ export default async function (cmdArgs) { async function serviceWorker() { const swDebug = { - file: join(buildDir, 'partytown-sw.debug.js'), + file: join(libBuildDir, 'partytown-sw.debug.js'), format: 'es', exports: 'none', plugins: [terser(debugOpts)], @@ -173,7 +173,7 @@ export default async function (cmdArgs) { const output = [swDebug]; if (!isDev) { output.push({ - file: join(buildDir, 'partytown-sw.js'), + file: join(libBuildDir, 'partytown-sw.js'), format: 'es', exports: 'none', plugins: [managlePropsPlugin(), terser(minOpts), fileSize()], @@ -219,7 +219,7 @@ export default async function (cmdArgs) { } }, writeBundle() { - copySync(buildDir, testsBuildDir); + copySync(libBuildDir, testsBuildDir); }, }, ], @@ -228,14 +228,14 @@ export default async function (cmdArgs) { function main() { const partytownDebug = { - file: join(buildDir, 'partytown.debug.js'), + file: join(libBuildDir, 'partytown.debug.js'), format: 'es', exports: 'none', plugins: [terser(debugOpts)], }; const partytownMin = { - file: join(buildDir, 'partytown.js'), + file: join(libBuildDir, 'partytown.js'), format: 'es', exports: 'none', plugins: [terser(minOpts), fileSize()], @@ -256,7 +256,7 @@ export default async function (cmdArgs) { }), { writeBundle() { - copySync(buildDir, testsBuildDir); + copySync(libBuildDir, testsBuildDir); }, }, ], @@ -265,14 +265,14 @@ export default async function (cmdArgs) { function snippet() { const partytownDebug = { - file: join(buildDir, 'partytown-snippet.debug.js'), + file: join(libBuildDir, 'partytown-snippet.debug.js'), format: 'iife', exports: 'none', plugins: [terser(debugOpts)], }; const partytownMin = { - file: join(buildDir, 'partytown-snippet.js'), + file: join(libBuildDir, 'partytown-snippet.js'), format: 'es', exports: 'none', plugins: [ @@ -305,7 +305,46 @@ export default async function (cmdArgs) { }), { writeBundle() { - copySync(buildDir, testsBuildDir); + copySync(libBuildDir, testsBuildDir); + }, + }, + ], + }; + } + + function defaultExport() { + const output = [ + { + file: join(rootDir, 'index.cjs'), + format: 'cjs', + }, + { + file: join(rootDir, 'index.mjs'), + format: 'es', + }, + ]; + + return { + input: join(srcDir, 'index.ts'), + output, + plugins: [ + typescript({ + cacheDir: join(cacheDir, 'default'), + outputToFilesystem: false, + }), + { + name: 'snippet', + resolveId(id) { + if (id.startsWith('@')) return id; + }, + async load(id) { + if (id === '@snippet') { + const codeFile = 'partytown-snippet.js'; + const code = readFileSync(join(libBuildDir, codeFile), 'utf-8').trim(); + return `const PartytownSnippet = ${JSON.stringify( + code + )}; export default PartytownSnippet;`; + } }, }, ], @@ -341,22 +380,26 @@ export default async function (cmdArgs) { ], external: ['react'], plugins: [ + { + resolveId(id) { + if (id === '../index') { + return { + external: true, + id, + }; + } + }, + }, typescript({ cacheDir: join(cacheDir, 'react'), outputToFilesystem: false, }), { - name: 'reactSnippet', - resolveId(id) { - if (id.startsWith('@')) return id; - }, - async load(id) { - if (id === '@snippet') { - const codeFile = isDev ? 'partytown-snippet.debug.js' : 'partytown-snippet.js'; - const code = readFileSync(join(buildDir, codeFile), 'utf-8').trim(); - return `const PartytownSnippet = ${JSON.stringify( - code - )}; export default PartytownSnippet;`; + name: 'moduleExtension', + generateBundle(opts, bundle) { + const ext = opts.format === 'cjs' ? 'cjs' : 'mjs'; + for (const f in bundle) { + bundle[f].code = bundle[f].code.replace(`../index`, `../index.${ext}`); } }, }, @@ -371,7 +414,7 @@ export default async function (cmdArgs) { }; } - return [await serviceWorker(), main(), snippet(), react()]; + return [await serviceWorker(), main(), snippet(), defaultExport(), react()]; } function managlePropsPlugin() { diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 00000000..a97a6653 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,18 @@ +import PartytownSnippet from '@snippet'; +import type { PartytownConfig } from './lib/types'; + +export const partytownSnippet = (config: PartytownConfig) => { + const forward = config.forward || []; + delete config.forward; + + return [ + `(function(w,p,f,c){`, + config && Object.keys(config).length > 0 + ? `c=w[p]=Object.assign(w[p]||{},${JSON.stringify(config)});` + : `c=w[p]=w[p]||{};`, + `c[f]=(c[f]||[])`, + forward.length > 0 ? `.concat(${JSON.stringify(forward)})` : ``, + `})(window,'partytown','forward');`, + PartytownSnippet, + ].join(''); +}; diff --git a/src/lib/modules.d.ts b/src/modules.d.ts similarity index 100% rename from src/lib/modules.d.ts rename to src/modules.d.ts diff --git a/src/react/partytown.tsx b/src/react/partytown.tsx index 890a1e53..eaa0a5c3 100644 --- a/src/react/partytown.tsx +++ b/src/react/partytown.tsx @@ -1,6 +1,6 @@ import React from 'react'; import type { PartytownConfig } from '../lib/types'; -import PartytownSnippet from '@snippet'; +import { partytownSnippet } from '../index'; /** * Props for ``, which extends the Partytown Config. @@ -17,27 +17,11 @@ export interface PartytownProps extends PartytownConfig {} * * @public */ -export const Partytown = (props?: PartytownProps): any => { - props = { ...props }; - const forward = props.forward || []; - delete props.forward; - - const config = [ - `(function(w,p,f,c){`, - Object.keys(props).length > 0 - ? `c=w[p]=Object.assign(w[p]||{},${JSON.stringify(props)});` - : `c=w[p]=w[p]||{};`, - `c[f]=(c[f]||[])`, - forward.length > 0 ? `.concat(${JSON.stringify(forward)})` : ``, - `})(window,'partytown','forward');`, - ]; - - return ( -