Skip to content

Commit 5b1edcd

Browse files
WIP
1 parent bbe841c commit 5b1edcd

File tree

8 files changed

+160
-87
lines changed

8 files changed

+160
-87
lines changed

packages/wmr/src/lib/npm-middleware.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ export function npmEtagCache() {
66
const url = new URL(req.url, 'https://localhost');
77
let id = path.posix.normalize(url.pathname);
88

9-
if (!id.startsWith('/@npm/@id/')) {
9+
if (!id.startsWith('/@npm/')) {
1010
return next();
1111
}
1212

13-
id = id.slice('/@npm/@id/'.length);
13+
id = id.slice('/@npm/'.length);
1414
if (!isValidPackageName(id)) {
1515
return next();
1616
}

packages/wmr/src/lib/plugins.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import path from 'path';
12
import htmPlugin from '../plugins/htm-plugin.js';
23
import sucrasePlugin from '../plugins/sucrase-plugin.js';
34
import wmrPlugin from '../plugins/wmr/plugin.js';
@@ -28,6 +29,7 @@ import { lessPlugin } from '../plugins/less-plugin.js';
2829
import { workerPlugin } from '../plugins/worker-plugin.js';
2930
import { npmPlugin } from '../plugins/npm-plugin/index.js';
3031
import tsConfigPathsPlugin from '../plugins/tsconfig-paths-plugin.js';
32+
import { getNpmPlugins } from '../plugins/npm-plugin/npm-bundle.js';
3133

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

56+
const npmCacheDir = path.join(cwd, '.cache', '@npm');
57+
58+
/**
59+
* Map of package name to folder on disk
60+
* @type {Map<string, string>}
61+
*/
62+
const resolutionCache = new Map();
63+
5464
// Plugins are pre-sorted
5565
let split = plugins.findIndex(p => p.enforce === 'post');
5666
if (split === -1) split = plugins.length;
@@ -102,7 +112,20 @@ export function getPlugins(options) {
102112
// Only transpile CommonJS in node_modules and explicit .cjs files:
103113
include: /(^npm\/|[/\\]node_modules[/\\]|\.cjs$)/
104114
}),
105-
npmPlugin({ cwd, autoInstall, production, registryUrl: registry }),
115+
116+
...(production
117+
? getNpmPlugins({
118+
autoInstall,
119+
production,
120+
cacheDir: npmCacheDir,
121+
cwd,
122+
registryUrl: registry,
123+
resolutionCache,
124+
browserReplacement: new Map()
125+
})
126+
: []),
127+
!production &&
128+
npmPlugin({ cwd, cacheDir: npmCacheDir, autoInstall, production, registryUrl: registry, resolutionCache }),
106129
resolveExtensionsPlugin({
107130
extensions: ['.ts', '.tsx', '.js', '.cjs'],
108131
index: true

packages/wmr/src/plugins/npm-plugin/commonjs.js

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,20 @@ export function commonjsPlugin({ production }) {
2020

2121
if (!hasCjsKeywords && hasEsmKeywords) return;
2222

23-
const result = transform(code, {
24-
parse: this.parse,
25-
plugins: [
26-
replace({ 'process.env.NODE_ENV': 'development', __DEV__: !!production }),
27-
optimize(),
28-
commonjsToEsm()
29-
]
30-
});
23+
let result;
24+
try {
25+
result = transform(code, {
26+
parse: this.parse,
27+
plugins: [
28+
replace({ 'process.env.NODE_ENV': 'development', __DEV__: !!production }),
29+
optimize(),
30+
commonjsToEsm()
31+
]
32+
});
33+
} catch (err) {
34+
console.log('ERR', code);
35+
throw err;
36+
}
3137

3238
return {
3339
code: result.code,

packages/wmr/src/plugins/npm-plugin/index.js

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ const log = debug('npm', 196);
1414
* @param {boolean} options.autoInstall
1515
* @param {boolean} options.production
1616
* @param {string} options.registryUrl
17+
* @param {string} options.cacheDir
18+
* @param {Map<string, string>} options.resolutionCache
1719
* @returns {import('rollup').Plugin}
1820
*/
19-
export function npmPlugin({ cwd, autoInstall, production, registryUrl }) {
21+
export function npmPlugin({ cwd, cacheDir, autoInstall, production, registryUrl, resolutionCache }) {
2022
const PREFIX = '\0npm:';
2123

22-
const cacheDir = path.join(cwd, '.cache', '@npm');
23-
2424
/** @type {Map<string, { code: string, map: any }>} */
2525
const chunkCache = new Map();
2626

@@ -88,17 +88,13 @@ export function npmPlugin({ cwd, autoInstall, production, registryUrl }) {
8888
return chunk;
8989
}
9090

91-
/**
92-
* Map of package name to folder on disk
93-
* @type {Map<string, string>}
94-
*/
95-
const resolutionCache = new Map();
96-
9791
return {
9892
name: 'npm-plugin',
9993
async resolveId(id) {
10094
if (!isValidPackageName(id)) return;
10195

96+
console.log('RESOLVE ID', JSON.stringify(id));
97+
10298
// Assets require special handling as other plugins need to deal with
10399
// non-js files during their `load()` method. To work around this
104100
// limitation in rollup's plugin system we'll pretend that we'd requested

packages/wmr/src/plugins/npm-plugin/npm-bundle.js

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,41 @@ function customWarn(warning) {
2222
onWarn(warning);
2323
}
2424

25+
/**
26+
* @param {object} options
27+
* @param {boolean} options.autoInstall
28+
* @param {boolean} options.production
29+
* @param {string} options.cacheDir
30+
* @param {string} options.cwd
31+
* @param {string} options.registryUrl
32+
* @param {string} [options.requestId]
33+
* @param {Map<string, string>} options.resolutionCache
34+
* @param {Map<string, string>} options.browserReplacement
35+
* @returns {import('rollup').Plugin[]}
36+
*/
37+
export function getNpmPlugins({
38+
autoInstall,
39+
production,
40+
cacheDir,
41+
cwd,
42+
resolutionCache,
43+
registryUrl,
44+
browserReplacement,
45+
requestId
46+
}) {
47+
// @ts-ignore
48+
return [
49+
browserFieldPlugin({ browserReplacement }),
50+
!production && requestId && npmExternalDeps({ requestId }),
51+
!process.env.DISABLE_LOCAL_NPM && npmLocalPackage({ root: cwd }),
52+
autoInstall && npmAutoInstall({ cacheDir, registryUrl }),
53+
npmLoad({ browserReplacement, resolutionCache }),
54+
commonjsPlugin({ production }),
55+
subPackageLegacy(),
56+
sizeWarningPlugin()
57+
].filter(Boolean);
58+
}
59+
2560
/**
2661
* @param {string} requestId
2762
* @param {object} options
@@ -39,22 +74,27 @@ export async function npmBundle(requestId, { autoInstall, production, cacheDir,
3974
/** @type {Map<string, string>} */
4075
const browserReplacement = new Map();
4176

77+
console.log('BUNDLE', requestId, meta, { production });
78+
4279
const bundle = await rollup.rollup({
4380
input: requestId,
4481
external: [...builtinModules],
4582
onwarn: customWarn,
4683
plugins: [
47-
browserFieldPlugin({ browserReplacement }),
48-
npmExternalDeps({ requestId }),
49-
!process.env.DISABLE_LOCAL_NPM && npmLocalPackage({ root: cwd }),
50-
autoInstall && npmAutoInstall({ cacheDir, registryUrl }),
51-
npmLoad({ browserReplacement, resolutionCache }),
52-
jsonPlugin({ root: cwd }),
53-
commonjsPlugin({ production }),
54-
subPackageLegacy({ rootId: requestId }),
55-
sizeWarningPlugin()
84+
...getNpmPlugins({
85+
requestId,
86+
autoInstall,
87+
production,
88+
cacheDir,
89+
cwd,
90+
resolutionCache,
91+
registryUrl,
92+
browserReplacement
93+
}),
94+
jsonPlugin({ root: cwd })
5695
]
5796
});
97+
console.log(resolutionCache);
5898

5999
const result = await bundle.generate({
60100
chunkFileNames: `${pkgName}-[hash]`,

packages/wmr/src/plugins/npm-plugin/sub-package-legacy.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,9 @@ import { isDirectory } from '../../lib/fs-utils.js';
55
/**
66
* Legacy way of defining package entry points before the
77
* "export" field in `package.json` was a thing.
8-
* @param {object} options
9-
* @param {string} options.rootId
108
* @returns {import('rollup').Plugin}
119
*/
12-
export function subPackageLegacy({ rootId }) {
10+
export function subPackageLegacy() {
1311
return {
1412
name: 'legacy-sub-package',
1513
async resolveId(id, importer) {

packages/wmr/src/wmr-middleware.js

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ export default function wmrMiddleware(options) {
246246

247247
// Workaround for transform forcing extensionless ids to be
248248
// non-js
249-
let hasIdPrefix = false;
249+
let isVirtual = false;
250250

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

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

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

280284
if (path.startsWith('/@id/')) {
281285
// Virtual paths have no exact file match, so we don't set `file`
282-
hasIdPrefix = true;
286+
isVirtual = true;
283287
path = path.slice('/@id'.length);
284288
}
285289

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

299-
if (!hasIdPrefix) {
303+
if (!isVirtual) {
300304
id = `./${id}`;
301305
}
302306

@@ -331,7 +335,7 @@ export default function wmrMiddleware(options) {
331335
} else if (queryParams.has('asset')) {
332336
cacheKey += '?asset';
333337
transform = TRANSFORMS.asset;
334-
} else if (prefix || hasIdPrefix || isModule || /\.([mc]js|[tj]sx?)$/.test(file) || STYLE_REG.test(file)) {
338+
} else if (prefix || isVirtual || isModule || /\.([mc]js|[tj]sx?)$/.test(file) || STYLE_REG.test(file)) {
335339
transform = TRANSFORMS.js;
336340
} else if (file.startsWith(root + sep) && (await isFile(file))) {
337341
// Ignore dotfiles
@@ -557,6 +561,7 @@ export const TRANSFORMS = {
557561
// const resolved = await NonRollup.resolveId(spec, importer);
558562
let originalSpec = spec;
559563
const resolved = await NonRollup.resolveId(spec, file);
564+
console.log({ originalSpec, resolved });
560565
if (resolved) {
561566
spec = typeof resolved == 'object' ? resolved.id : resolved;
562567
// Some rollup plugins use absolute paths as virtual identifiers :/
@@ -591,7 +596,7 @@ export const TRANSFORMS = {
591596
spec = relative(root, spec).split(sep).join(posix.sep);
592597
}
593598
// Retain bare specifiers when serializing to url
594-
else if (!/^\.?\.\//.test(spec)) {
599+
else if (!/^\.?\.\//.test(spec) && prefix !== 'npm') {
595600
spec = `@id/${spec}`;
596601
}
597602

0 commit comments

Comments
 (0)