Skip to content

Commit

Permalink
Merge pull request #213 from remix-pwa/dev
Browse files Browse the repository at this point in the history
Moving `@remix-pwa/dev` patches upstream
  • Loading branch information
ShafSpecs committed Apr 26, 2024
2 parents 08a7364 + fbc2d54 commit 25abb06
Show file tree
Hide file tree
Showing 10 changed files with 4,865 additions and 6,630 deletions.
459 changes: 399 additions & 60 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"@commitlint/config-conventional": "^19.1.0",
"@commitlint/prompt-cli": "^19.2.0",
"@types/chokidar": "^2.1.3",
"@types/node": "^20.11.25",
"@types/node": "^20.12.7",
"@types/semver": "^7.5.8",
"@vitest/coverage-v8": "^1.5.0",
"chokidar": "^3.5.0",
Expand All @@ -51,4 +51,4 @@
"engines": {
"node": ">=18.0.0"
}
}
}
7 changes: 7 additions & 0 deletions packages/dev/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## @remix-pwa/dev 3.0.5-dev.1 (2024-04-26)


### Bug Fixes

* **dev:** now reduced bundle size of service worker by ~25% ec5760c

## @remix-pwa/dev 3.0.4 (2024-04-08)


Expand Down
2 changes: 1 addition & 1 deletion packages/dev/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@remix-pwa/dev",
"version": "3.0.4",
"version": "3.0.5-dev.1",
"description": "An esbuild compiler for Service Workers in Remix.run",
"repository": {
"type": "git",
Expand Down
74 changes: 58 additions & 16 deletions packages/dev/src/plugins/__test__/virtual-sw-plugin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,69 +282,111 @@ describe('Remix PWA Vite VirtualSW Plugin', () => {
plugin = _plugin(mockContext);
});

describe('Virtual Entry Plugin', () => {
describe('Virtual Empty Modules Plugin', () => {
test('should return a plugin object', () => {
expect(plugin[0]).not.toBe(null);
expect(plugin[0]).toBeTypeOf('object');
});

test('should resolve to the correct plugin name', () => {
expect(plugin[0].name).toBe('vite-plugin-remix-pwa:empty-modules-sw');
});

test('should run before vite build hooks', () => {
expect(plugin[0].enforce).toBe('pre');
});

test('should return an empty module for flagged packages', async () => {
expect(await plugin[0].load('react')).toBe('module.exports = {};');
expect(await plugin[0].load('react-dom')).toBe('module.exports = {};');
});

test('should remove non-license jsdoc comments from code', async () => {
const code = `
/**
* @example This is an example comment
* This is a license comment
*/
const a = 1;`;
expect((await plugin[0].transform(code)).trim()).toBe('const a = 1;');

const code2 = `
/**
* @license MIT
* This is a license comment
*/
const a = 1;`;
expect((await plugin[0].transform(code2)).trimStart()).toBe(`/**
* @license MIT
* This is a license comment
*/
const a = 1;`);
});
});

describe('Virtual Entry Plugin', () => {
test('should return a plugin object', () => {
expect(plugin[1]).not.toBe(null);
expect(plugin[1]).toBeTypeOf('object');
});

test('should have the correct name', () => {
expect(plugin[0].name).toBe('vite-plugin-remix-pwa:virtual-entry-sw');
expect(plugin[1].name).toBe('vite-plugin-remix-pwa:virtual-entry-sw');
});

test('should resolve the virtual entry id correctly', () => {
expect(plugin[0].resolveId('virtual:entry-sw')).toBe('\0virtual:entry-sw');
expect(plugin[1].resolveId('virtual:entry-sw')).toBe('\0virtual:entry-sw');
});

test('should load the virtual entry module', async () => {
expect(await plugin[0].load('\0virtual:entry-sw')).toContain('export const routes = {');
expect(await plugin[0].load('\0virtual:entry-sw')).toContain('export const entry = { module: entryWorker }');
expect(await plugin[1].load('\0virtual:entry-sw')).toContain('export const routes = {');
expect(await plugin[1].load('\0virtual:entry-sw')).toContain('export const entry = { module: entryWorker }');
});
});

describe('Virtual Routes Plugin', () => {
test('should return a plugin object', () => {
expect(plugin[1]).not.toBe(null);
expect(plugin[1]).toBeTypeOf('object');
expect(plugin[2]).not.toBe(null);
expect(plugin[2]).toBeTypeOf('object');
});

test('should have the correct name', () => {
expect(plugin[1].name).toBe('vite-plugin-remix-pwa:virtual-routes-sw');
expect(plugin[2].name).toBe('vite-plugin-remix-pwa:virtual-routes-sw');
});

test('should resolve the virtual routes id correctly', () => {
expect(plugin[1].resolveId('virtual:worker:routes/home.tsx')).toBe('virtual:worker:routes/home.tsx');
expect(plugin[2].resolveId('virtual:worker:routes/home.tsx')).toBe('virtual:worker:routes/home.tsx');
});

test('should provide a virtual module for virtual worker files on load', async () => {
const result = await plugin[1].load('virtual:worker:routes/about.tsx');
const result = await plugin[2].load('virtual:worker:routes/about.tsx');

expect(result).toContain('export const workerLoader = () => {');
});

test("should return an empty module if the route doesn't contain worker route apis", async () => {
const result = await plugin[1].load('virtual:worker:routes/home.tsx');
const result = await plugin[2].load('virtual:worker:routes/home.tsx');

expect(result).toBe('module.exports = {}');
});
});

describe('Virtual Assets Plugin', () => {
test('should return a plugin object', () => {
expect(plugin[2]).not.toBe(null);
expect(plugin[2]).toBeTypeOf('object');
expect(plugin[3]).not.toBe(null);
expect(plugin[3]).toBeTypeOf('object');
});

test('should have the correct name', () => {
expect(plugin[2].name).toBe('vite-plugin-remix-pwa:virtual-assets-sw');
expect(plugin[3].name).toBe('vite-plugin-remix-pwa:virtual-assets-sw');
});

test('should resolve the virtual entry id correctly', () => {
expect(plugin[2].resolveId('virtual:assets-sw')).toBe('\0virtual:assets-sw');
expect(plugin[3].resolveId('virtual:assets-sw')).toBe('\0virtual:assets-sw');
});

test.skipIf(process.env.VITEST_WORKSPACE)('should return the build assets on load', async () => {
const assetPlugin = await plugin[2].load('\0virtual:assets-sw');
const assetPlugin = await plugin[3].load('\0virtual:assets-sw');

expect(assetPlugin).toBeTypeOf('string');

Expand Down
26 changes: 26 additions & 0 deletions packages/dev/src/plugins/virtual-sw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,35 @@ export function VirtualSWPlugins(ctx: PWAPluginContext): Plugin[] {
const entryId = VirtualModule.id('entry-sw');
const assetsId = VirtualModule.id('assets-sw');

const emptyFileName = VirtualModule.resolve('remix_pwa_plugin_ignore_empty_module_placeholder');

const workerRouteCache = new Map();

return <Plugin[]>[
{
name: 'vite-plugin-remix-pwa:empty-modules-sw',
enforce: 'pre',
async load(id) {
if (
id === emptyFileName ||
id.match(/@remix-run\/(deno|cloudflare|node|react)(\/.*)/g) ||
id.match(/react(-dom)?(\/.*)?$/g) ||
id.match(/\.server/g) ||
id.match(/web-push?$/g)
) {
return 'module.exports = {};';
}
},
async transform(code) {
const regex = /\/\*\*[\s\S]*?\*\//g;

const licenseComments = code.match(regex)?.filter(predicate => /@license/.test(predicate)) ?? [];
return code.replaceAll(regex, match => {
if (licenseComments?.includes(match)) return match;
return '';
});
},
},
{
name: 'vite-plugin-remix-pwa:virtual-entry-sw',
resolveId(id) {
Expand Down
Loading

0 comments on commit 25abb06

Please sign in to comment.