Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
marvinhagemeister committed Oct 6, 2021
1 parent bbe841c commit 5b1edcd
Show file tree
Hide file tree
Showing 8 changed files with 160 additions and 87 deletions.
4 changes: 2 additions & 2 deletions packages/wmr/src/lib/npm-middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ export function npmEtagCache() {
const url = new URL(req.url, 'https://localhost');
let id = path.posix.normalize(url.pathname);

if (!id.startsWith('/@npm/@id/')) {
if (!id.startsWith('/@npm/')) {
return next();
}

id = id.slice('/@npm/@id/'.length);
id = id.slice('/@npm/'.length);
if (!isValidPackageName(id)) {
return next();
}
Expand Down
25 changes: 24 additions & 1 deletion packages/wmr/src/lib/plugins.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import path from 'path';
import htmPlugin from '../plugins/htm-plugin.js';
import sucrasePlugin from '../plugins/sucrase-plugin.js';
import wmrPlugin from '../plugins/wmr/plugin.js';
Expand Down Expand Up @@ -28,6 +29,7 @@ import { lessPlugin } from '../plugins/less-plugin.js';
import { workerPlugin } from '../plugins/worker-plugin.js';
import { npmPlugin } from '../plugins/npm-plugin/index.js';
import tsConfigPathsPlugin from '../plugins/tsconfig-paths-plugin.js';
import { getNpmPlugins } from '../plugins/npm-plugin/npm-bundle.js';

/**
* @param {import("wmr").Options & { isIIFEWorker?: boolean}} options
Expand All @@ -51,6 +53,14 @@ export function getPlugins(options) {
registry
} = options;

const npmCacheDir = path.join(cwd, '.cache', '@npm');

/**
* Map of package name to folder on disk
* @type {Map<string, string>}
*/
const resolutionCache = new Map();

// Plugins are pre-sorted
let split = plugins.findIndex(p => p.enforce === 'post');
if (split === -1) split = plugins.length;
Expand Down Expand Up @@ -102,7 +112,20 @@ export function getPlugins(options) {
// Only transpile CommonJS in node_modules and explicit .cjs files:
include: /(^npm\/|[/\\]node_modules[/\\]|\.cjs$)/
}),
npmPlugin({ cwd, autoInstall, production, registryUrl: registry }),

...(production
? getNpmPlugins({
autoInstall,
production,
cacheDir: npmCacheDir,
cwd,
registryUrl: registry,
resolutionCache,
browserReplacement: new Map()
})
: []),
!production &&
npmPlugin({ cwd, cacheDir: npmCacheDir, autoInstall, production, registryUrl: registry, resolutionCache }),
resolveExtensionsPlugin({
extensions: ['.ts', '.tsx', '.js', '.cjs'],
index: true
Expand Down
22 changes: 14 additions & 8 deletions packages/wmr/src/plugins/npm-plugin/commonjs.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,20 @@ export function commonjsPlugin({ production }) {

if (!hasCjsKeywords && hasEsmKeywords) return;

const result = transform(code, {
parse: this.parse,
plugins: [
replace({ 'process.env.NODE_ENV': 'development', __DEV__: !!production }),
optimize(),
commonjsToEsm()
]
});
let result;
try {
result = transform(code, {
parse: this.parse,
plugins: [
replace({ 'process.env.NODE_ENV': 'development', __DEV__: !!production }),
optimize(),
commonjsToEsm()
]
});
} catch (err) {
console.log('ERR', code);
throw err;
}

return {
code: result.code,
Expand Down
14 changes: 5 additions & 9 deletions packages/wmr/src/plugins/npm-plugin/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ const log = debug('npm', 196);
* @param {boolean} options.autoInstall
* @param {boolean} options.production
* @param {string} options.registryUrl
* @param {string} options.cacheDir
* @param {Map<string, string>} options.resolutionCache
* @returns {import('rollup').Plugin}
*/
export function npmPlugin({ cwd, autoInstall, production, registryUrl }) {
export function npmPlugin({ cwd, cacheDir, autoInstall, production, registryUrl, resolutionCache }) {
const PREFIX = '\0npm:';

const cacheDir = path.join(cwd, '.cache', '@npm');

/** @type {Map<string, { code: string, map: any }>} */
const chunkCache = new Map();

Expand Down Expand Up @@ -88,17 +88,13 @@ export function npmPlugin({ cwd, autoInstall, production, registryUrl }) {
return chunk;
}

/**
* Map of package name to folder on disk
* @type {Map<string, string>}
*/
const resolutionCache = new Map();

return {
name: 'npm-plugin',
async resolveId(id) {
if (!isValidPackageName(id)) return;

console.log('RESOLVE ID', JSON.stringify(id));

// Assets require special handling as other plugins need to deal with
// non-js files during their `load()` method. To work around this
// limitation in rollup's plugin system we'll pretend that we'd requested
Expand Down
58 changes: 49 additions & 9 deletions packages/wmr/src/plugins/npm-plugin/npm-bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,41 @@ function customWarn(warning) {
onWarn(warning);
}

/**
* @param {object} options
* @param {boolean} options.autoInstall
* @param {boolean} options.production
* @param {string} options.cacheDir
* @param {string} options.cwd
* @param {string} options.registryUrl
* @param {string} [options.requestId]
* @param {Map<string, string>} options.resolutionCache
* @param {Map<string, string>} options.browserReplacement
* @returns {import('rollup').Plugin[]}
*/
export function getNpmPlugins({
autoInstall,
production,
cacheDir,
cwd,
resolutionCache,
registryUrl,
browserReplacement,
requestId
}) {
// @ts-ignore
return [
browserFieldPlugin({ browserReplacement }),
!production && requestId && npmExternalDeps({ requestId }),
!process.env.DISABLE_LOCAL_NPM && npmLocalPackage({ root: cwd }),
autoInstall && npmAutoInstall({ cacheDir, registryUrl }),
npmLoad({ browserReplacement, resolutionCache }),
commonjsPlugin({ production }),
subPackageLegacy(),
sizeWarningPlugin()
].filter(Boolean);
}

/**
* @param {string} requestId
* @param {object} options
Expand All @@ -39,22 +74,27 @@ export async function npmBundle(requestId, { autoInstall, production, cacheDir,
/** @type {Map<string, string>} */
const browserReplacement = new Map();

console.log('BUNDLE', requestId, meta, { production });

const bundle = await rollup.rollup({
input: requestId,
external: [...builtinModules],
onwarn: customWarn,
plugins: [
browserFieldPlugin({ browserReplacement }),
npmExternalDeps({ requestId }),
!process.env.DISABLE_LOCAL_NPM && npmLocalPackage({ root: cwd }),
autoInstall && npmAutoInstall({ cacheDir, registryUrl }),
npmLoad({ browserReplacement, resolutionCache }),
jsonPlugin({ root: cwd }),
commonjsPlugin({ production }),
subPackageLegacy({ rootId: requestId }),
sizeWarningPlugin()
...getNpmPlugins({
requestId,
autoInstall,
production,
cacheDir,
cwd,
resolutionCache,
registryUrl,
browserReplacement
}),
jsonPlugin({ root: cwd })
]
});
console.log(resolutionCache);

const result = await bundle.generate({
chunkFileNames: `${pkgName}-[hash]`,
Expand Down
4 changes: 1 addition & 3 deletions packages/wmr/src/plugins/npm-plugin/sub-package-legacy.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@ import { isDirectory } from '../../lib/fs-utils.js';
/**
* Legacy way of defining package entry points before the
* "export" field in `package.json` was a thing.
* @param {object} options
* @param {string} options.rootId
* @returns {import('rollup').Plugin}
*/
export function subPackageLegacy({ rootId }) {
export function subPackageLegacy() {
return {
name: 'legacy-sub-package',
async resolveId(id, importer) {
Expand Down
17 changes: 11 additions & 6 deletions packages/wmr/src/wmr-middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ export default function wmrMiddleware(options) {

// Workaround for transform forcing extensionless ids to be
// non-js
let hasIdPrefix = false;
let isVirtual = false;

let file = '';
let id = path;
Expand All @@ -257,14 +257,18 @@ export default function wmrMiddleware(options) {
// Path for virtual modules that refer to an unprefixed id.
if (path.startsWith('/@id/')) {
// Virtual paths have no exact file match, so we don't set `file`
hasIdPrefix = true;
isVirtual = true;
id = path.slice('/@id/'.length);

// Add back leading slash if it was part of the virtual id.
// Example: `/@windicss/windi.css`
if (req.path.startsWith('/@id//')) {
id = '/' + id;
}
} else if (path.startsWith('/@npm/')) {
// Virtual paths have no exact file match, so we don't set `file`
id = path.slice('/@npm/'.length);
isVirtual = true;
} else if (path.startsWith('/@alias/')) {
id = posix.normalize(path.slice('/@alias/'.length));

Expand All @@ -279,7 +283,7 @@ export default function wmrMiddleware(options) {

if (path.startsWith('/@id/')) {
// Virtual paths have no exact file match, so we don't set `file`
hasIdPrefix = true;
isVirtual = true;
path = path.slice('/@id'.length);
}

Expand All @@ -296,7 +300,7 @@ export default function wmrMiddleware(options) {
// Normalize the cacheKey so it matches what will be in the WRITE_CACHE, where we store in native paths
cacheKey = cacheKey.split(posix.sep).join(sep);

if (!hasIdPrefix) {
if (!isVirtual) {
id = `./${id}`;
}

Expand Down Expand Up @@ -331,7 +335,7 @@ export default function wmrMiddleware(options) {
} else if (queryParams.has('asset')) {
cacheKey += '?asset';
transform = TRANSFORMS.asset;
} else if (prefix || hasIdPrefix || isModule || /\.([mc]js|[tj]sx?)$/.test(file) || STYLE_REG.test(file)) {
} else if (prefix || isVirtual || isModule || /\.([mc]js|[tj]sx?)$/.test(file) || STYLE_REG.test(file)) {
transform = TRANSFORMS.js;
} else if (file.startsWith(root + sep) && (await isFile(file))) {
// Ignore dotfiles
Expand Down Expand Up @@ -557,6 +561,7 @@ export const TRANSFORMS = {
// const resolved = await NonRollup.resolveId(spec, importer);
let originalSpec = spec;
const resolved = await NonRollup.resolveId(spec, file);
console.log({ originalSpec, resolved });
if (resolved) {
spec = typeof resolved == 'object' ? resolved.id : resolved;
// Some rollup plugins use absolute paths as virtual identifiers :/
Expand Down Expand Up @@ -591,7 +596,7 @@ export const TRANSFORMS = {
spec = relative(root, spec).split(sep).join(posix.sep);
}
// Retain bare specifiers when serializing to url
else if (!/^\.?\.\//.test(spec)) {
else if (!/^\.?\.\//.test(spec) && prefix !== 'npm') {
spec = `@id/${spec}`;
}

Expand Down
Loading

0 comments on commit 5b1edcd

Please sign in to comment.