Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix virtual specifiers starting with /@ not being supported #812

Merged
merged 1 commit into from
Aug 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/cyan-timers-jump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'wmr': patch
---

Add a workaround to support virtual identifiers starting with `/@` to support `rollup-plugin-windicss`.
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