-
Notifications
You must be signed in to change notification settings - Fork 256
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: polyfill prefixed values (#503) * Map outline to colors (#502) * feat: allow utils to override polyfills (#504) * feature: experimental insertion method (#501) * Create CODEOWNERS (#510) * Remove `version` from root `package.json` (#511) * Chore: Improve project linting, building, packages (#514) * feat: delay less writes (#513) * chore: bump dependencies, fix build:watch script * feat: background ssr insertion (#515) * Fix: Support repeated local tokens (#520) * fix: support repeated local tokens * wip: update test to include 3 examples * wip: fixed * simplify default insertion method Co-authored-by: Pedro Duarte <contact@peduarte.com>
- Loading branch information
1 parent
1184127
commit d2a1a0d
Showing
21 changed files
with
461 additions
and
213 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,142 @@ | ||
import buildPackage from './build-package.js' | ||
import fs from './internal/fs.js' | ||
import { bold, underline } from './internal/color.js' | ||
import { corePackageUrl, reactPackageUrl, stringifyPackageUrl } from './internal/dirs.js' | ||
import { argv, isProcessMeta, getProcessArgOf } from './internal/process.js' | ||
import esbuild from 'esbuild' | ||
import fs from './internal/fs.js' | ||
import nodemon from 'nodemon' | ||
import zlib from 'zlib' | ||
import { minify } from 'terser' | ||
|
||
const variants = { | ||
esm: { | ||
extension: 'mjs', | ||
transform(code, exports) { | ||
const esmExports = [] | ||
for (const name in exports) esmExports.push(`${exports[name]} as ${name}`) | ||
return `${code}export{${esmExports.join(',')}}` | ||
}, | ||
}, | ||
cjs: { | ||
extension: 'cjs', | ||
transform(code, exports) { | ||
const cjsExports = [] | ||
for (const name in exports) cjsExports.push(`${name}:${exports[name]}`) | ||
return `${code}module.exports={${cjsExports.join(',')}}` | ||
}, | ||
}, | ||
iife: { | ||
extension: 'iife.js', | ||
transform(code, exports) { | ||
const iifeExports = [] | ||
for (const name in exports) iifeExports.push(`${name}:${exports[name]}`) | ||
return `(()=>{${code}globalThis.stitches={${iifeExports.join(',')}}})()` | ||
}, | ||
}, | ||
} | ||
|
||
export const build = async (packageUrl, opts) => { | ||
opts = Object.assign({ only: [] }, opts) | ||
|
||
const initPackageUrl = new URL('src/', packageUrl) | ||
const distPackageUrl = new URL('dist/', packageUrl) | ||
|
||
const packageJsonUrl = new URL(`package.json`, packageUrl) | ||
const packageName = JSON.parse(await fs.readFile(packageJsonUrl, 'utf8')).name | ||
|
||
if (!opts.only.length || opts.only.includes(packageName)) { | ||
console.log() | ||
console.log(underline(bold(packageName))) | ||
console.log() | ||
|
||
const targetPathname = new URL('index.js', initPackageUrl).pathname | ||
const outputPathname = new URL('stitches.js', distPackageUrl).pathname | ||
|
||
async function build() { | ||
console.log() | ||
// Build ESM version | ||
const { | ||
outputFiles: [cmapResult, codeResult], | ||
} = await esbuild.build({ | ||
entryPoints: [targetPathname], | ||
outfile: outputPathname, | ||
bundle: true, | ||
format: 'esm', | ||
sourcemap: 'external', | ||
write: false, | ||
}) | ||
|
||
await fs.rmdir(new URL('dist/', corePackageUrl), { recursive: true }) | ||
await fs.rmdir(new URL('dist/', reactPackageUrl), { recursive: true }) | ||
await fs.rmdir(new URL('dist/', stringifyPackageUrl), { recursive: true }) | ||
// Minify ESM version | ||
const { code, map } = await minify(codeResult.text, { | ||
sourceMap: { content: cmapResult.text }, | ||
compress: true, | ||
module: true, | ||
mangle: true, | ||
toplevel: true, | ||
}) | ||
|
||
await buildPackage(corePackageUrl) | ||
// ensure empty dist directory | ||
await fs.mkdir(distPackageUrl, { recursive: true }) | ||
|
||
console.log() | ||
await buildPackage(reactPackageUrl) | ||
// write map | ||
fs.writeFile(new URL(`index.map`, distPackageUrl), map) | ||
|
||
console.log() | ||
await buildPackage(stringifyPackageUrl) | ||
// prepare variations | ||
const splitByExport = (code, index = code.indexOf('export')) => [code.slice(0, index), code.slice(index)] | ||
const [lead, tail] = splitByExport(code) | ||
|
||
console.log() | ||
const exports = Array.from(tail.matchAll(/([$\w]+) as (\w+)/g)).reduce((exports, each) => Object.assign(exports, { [each[2]]: each[1] }), Object.create(null)) | ||
|
||
// write variation builds | ||
for (const variant in variants) { | ||
const variantInfo = variants[variant] | ||
const variantPath = new URL(`dist/index.${variantInfo.extension}`, packageUrl).pathname | ||
const variantCode = variantInfo.transform(lead, exports) | ||
const variantSize = Number((zlib.gzipSync(variantCode, { level: 9 }).length / 1000).toFixed(2)) | ||
|
||
console.log(' ', `\x1b[33m${variantSize} kB\x1b[0m`, `\x1b[2m(${variant})\x1b[0m`) | ||
|
||
await fs.writeFile(variantPath, variantCode + `\n//# sourceMappingUrl=index.map`) | ||
} | ||
} | ||
} | ||
|
||
export const buildAll = async (opts) => { | ||
await build(stringifyPackageUrl, opts) | ||
await build(corePackageUrl, opts) | ||
await build(reactPackageUrl, opts) | ||
} | ||
|
||
const metaUrl = new URL(import.meta.url) | ||
const argvUrl = new URL(process.argv[1], 'file:') | ||
if (isProcessMeta(import.meta)) { | ||
if (getProcessArgOf('watch').includes(true)) { | ||
let onlyArgs = getProcessArgOf('only') | ||
|
||
if (metaUrl.href === argvUrl.href) build() | ||
onlyArgs = onlyArgs.length ? ['--only', ...onlyArgs] : onlyArgs | ||
|
||
nodemon( | ||
[ | ||
// prettier-ignore | ||
'-q', | ||
`--watch packages/core/src`, | ||
`--watch packages/core/tests`, | ||
`--watch packages/core/types`, | ||
`--watch packages/react/src`, | ||
`--watch packages/react/tests`, | ||
`--watch packages/react/types`, | ||
|
||
// exec | ||
`--exec "${['node', './.bin/build.js', ...onlyArgs].join(' ')}"`, | ||
].join(' '), | ||
) | ||
.on('start', () => { | ||
process.stdout.write('\u001b[3J\u001b[2J\u001b[1J') | ||
console.clear() | ||
}) | ||
.on('quit', () => process.exit()) | ||
} else { | ||
buildAll({ | ||
only: getProcessArgOf('only'), | ||
}).catch((error) => { | ||
console.error(error) | ||
|
||
process.exitCode = 1 | ||
}) | ||
} | ||
} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
export const { | ||
argv: [exec, file, ...argv], | ||
} = process | ||
|
||
export const fileUrl = new URL(file, 'file:') | ||
|
||
/** Returns whether the import.meta matches the current process. */ | ||
export const isProcessMeta = (meta) => { | ||
const metaUrl = new URL(meta.url) | ||
|
||
return metaUrl.href === fileUrl.href | ||
} | ||
|
||
/** Returns the values for a given process argument. */ | ||
export const getProcessArgOf = (name) => { | ||
const lead = argv.indexOf('--' + name) + 1 | ||
const tail = lead ? argv.slice(lead).findIndex((arg) => arg.startsWith('--')) : 0 | ||
|
||
const vals = lead ? argv.slice(lead, ~tail ? lead + tail : argv.length) : [] | ||
|
||
return lead ? (vals.length ? vals : [true]) : vals | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import cp from 'child_process' | ||
import { rootUrl } from './dirs.js' | ||
|
||
export const spawn = async ({ exec = 'node', args = [], opts = {} }) => | ||
await new Promise((close, error) => { | ||
opts = Object.assign( | ||
{ | ||
cwd: rootUrl.pathname, | ||
env: { ...process.env }, | ||
stdio: 'inherit', | ||
}, | ||
opts, | ||
) | ||
|
||
cp.spawn(exec, args, opts)._events = { close, error } | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import fs from './internal/fs.js' | ||
import { bold, underline } from './internal/color.js' | ||
import { corePackageUrl, reactPackageUrl, stringifyPackageUrl } from './internal/dirs.js' | ||
import { isProcessMeta, getProcessArgOf } from './internal/process.js' | ||
import { ESLint } from 'eslint' | ||
|
||
export const lint = async (packageUrl, opts) => { | ||
opts = Object.assign({ only: [] }, opts) | ||
|
||
const packageJsonUrl = new URL(`package.json`, packageUrl) | ||
const packageName = JSON.parse(await fs.readFile(packageJsonUrl, 'utf8')).name | ||
const packageTsUrl = new URL(`types/index.d.ts`, packageUrl) | ||
|
||
if (!opts.only.length || opts.only.includes(packageName)) { | ||
console.log(underline(bold(packageName))) | ||
console.log(packageTsUrl.pathname) | ||
|
||
const eslint = new ESLint() | ||
|
||
const results = await eslint.lintFiles([packageTsUrl.pathname]) | ||
|
||
const formatter = await eslint.loadFormatter('stylish') | ||
const resultText = formatter.format(results) | ||
|
||
if (resultText) console.log(resultText) | ||
else console.log('\x1b[32m✔\x1b[0m', 'Your code is flawless.', 'Hopefully this determination is flawless, too.') | ||
} | ||
} | ||
|
||
export const lintAll = async (opts) => { | ||
await lint(stringifyPackageUrl, opts) | ||
await lint(corePackageUrl, opts) | ||
await lint(reactPackageUrl, opts) | ||
} | ||
|
||
if (isProcessMeta(import.meta)) { | ||
lintAll({ | ||
only: getProcessArgOf('only'), | ||
}).catch((error) => { | ||
console.error(error) | ||
|
||
process.exitCode = 1 | ||
}) | ||
} |
Oops, something went wrong.