Skip to content

Commit

Permalink
Fix virtual specifiers starting with /@ not being supported
Browse files Browse the repository at this point in the history
  • Loading branch information
marvinhagemeister committed Aug 29, 2021
1 parent 6e8d710 commit 951b3a6
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 9 deletions.
20 changes: 13 additions & 7 deletions packages/wmr/src/plugins/wmr/styles/styles-plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,16 +99,22 @@ export default function wmrStylesPlugin({ root, hot, production, alias, sourcema
}
});

// Preserve asset path to avoid file clashes:
// foo/styles.module.css
// bar/styles.module.css
// Both files above should not overwrite each other.
// We don't have that problem in production, because
// assets are hashed
let fileName;
if (!production) {
fileName = id.startsWith('/@') ? `@id/${id}` : id;
fileName += '?asset';
}

const ref = this.emitFile({
type: 'asset',
name: basename(id).replace(/\.(s[ac]ss|less)$/, '.css'),
// Preserve asset path to avoid file clashes:
// foo/styles.module.css
// bar/styles.module.css
// Both files above should not overwrite each other.
// We don't have that problem in production, because
// assets are hashed
fileName: !production ? id + '?asset' : undefined,
fileName,
source
});

Expand Down
14 changes: 12 additions & 2 deletions packages/wmr/src/wmr-middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,12 @@ export default function wmrMiddleware(options) {
// Virtual paths have no exact file match, so we don't set `file`
hasIdPrefix = 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('/@alias/')) {
id = posix.normalize(path.slice('/@alias/'.length));

Expand Down Expand Up @@ -534,7 +540,11 @@ export const TRANSFORMS = {
const resolved = await NonRollup.resolveId(spec, file);
if (resolved) {
spec = typeof resolved == 'object' ? resolved.id : resolved;
if (/^(\/|\\|[a-z]:\\)/i.test(spec)) {
// Some rollup plugins use absolute paths as virtual identifiers :/
// Example: `/@windicss/windi.css`
if (/^\/@/.test(spec)) {
spec = `/@id/${spec}`;
} else if (/^(\/|\\|[a-z]:\\)/i.test(spec)) {
spec = relative(dirname(file), spec).split(sep).join(posix.sep);
if (!/^\.?\.?\//.test(spec)) {
spec = './' + spec;
Expand Down Expand Up @@ -579,7 +589,7 @@ export const TRANSFORMS = {
if (aliased) spec = aliased;
}

if (!spec.startsWith('/@alias/') && !/^\0?\.?\.?[/\\]/.test(spec)) {
if (!spec.startsWith('/@id/') && !spec.startsWith('/@alias/') && !/^\0?\.?\.?[/\\]/.test(spec)) {
// Check if the spec is an alias
const aliased = matchAlias(alias, spec);
if (aliased) spec = aliased;
Expand Down
12 changes: 12 additions & 0 deletions packages/wmr/test/fixtures.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,18 @@ describe('fixtures', () => {
expect(text).toMatch('it works');
});

// Issue #811
it('should support virtual ids starting with /@', async () => {
await loadFixture('virtual-id-at', env);
instance = await runWmrFast(env.tmp.path);
await getOutput(env, instance);

await waitForPass(async () => {
const color = await env.page.$eval('h1', el => getComputedStyle(el).color);
expect(color).toBe('rgb(255, 0, 0)');
});
});

it('should prioritize extensionless import by extension array', async () => {
await loadFixture('import-priority', env);
instance = await runWmrFast(env.tmp.path);
Expand Down
2 changes: 2 additions & 0 deletions packages/wmr/test/fixtures/virtual-id-at/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<h1>foo</h1>
<script src="./index.js" type="module"></script>
1 change: 1 addition & 0 deletions packages/wmr/test/fixtures/virtual-id-at/public/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import 'virtual:windi.css';
22 changes: 22 additions & 0 deletions packages/wmr/test/fixtures/virtual-id-at/wmr.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
export default function () {
const ID = 'virtual:windi.css';
const VIRTUAL_ID = '/@windicss/windi.css';

return {
plugins: [
{
name: 'virtual-id-plugin',
resolveId(id) {
if (id === ID) {
return VIRTUAL_ID;
}
},
load(id) {
if (id === VIRTUAL_ID) {
return `h1 { color: red; }`;
}
}
}
]
};
}
18 changes: 18 additions & 0 deletions packages/wmr/test/production.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,24 @@ describe('production', () => {
expect(text).toMatch(/it works/);
});

// Issue #811
it('should support virtual ids starting with /@', async () => {
await loadFixture('virtual-id-at', env);
instance = await runWmr(env.tmp.path, 'build');
const code = await instance.done;
expect(code).toEqual(0);

const { address, stop } = serveStatic(path.join(env.tmp.path, 'dist'));
cleanup.push(stop);

await env.page.goto(address, {
waitUntil: ['networkidle0', 'load']
});

const color = await env.page.$eval('h1', el => getComputedStyle(el).color);
expect(color).toBe('rgb(255, 0, 0)');
});

it("should preserve './' for relative specifiers", async () => {
await loadFixture('plugin-resolve', env);
instance = await runWmr(env.tmp.path, 'build');
Expand Down

0 comments on commit 951b3a6

Please sign in to comment.