Skip to content

Commit ad3a53f

Browse files
authored
fix: use vite build instead of rollup (#147)
This fix includes vite configuration and build command changes. Straightforward migration does not work due to 'sha256 digest missing' error at runtime. The reason of the error is the way vite bundling object-hash module. The module has two entries main and browser in package.json pointing to module's js files. Vite bundles both files and they behaves not the same way when loaded by nodejs. Making module external solves the issue, but object-hash module must be installed next to extension.cjs to be loaded during extension activation. Signed-off-by: Denis Golovin <[email protected]>
1 parent d2363f9 commit ad3a53f

File tree

8 files changed

+299
-173
lines changed

8 files changed

+299
-173
lines changed

.extfiles

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package.json
2+
LICENSE
3+
icon.png
4+
redhat-icon.woff2
5+
README.md
6+
dist/**
7+
www/**

package.json

+11-15
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"engines": {
1010
"podman-desktop": "^1.10.0"
1111
},
12-
"main": "./dist/extension.js",
12+
"main": "./dist/extension.cjs",
1313
"contributes": {
1414
"commands": [
1515
{
@@ -32,40 +32,37 @@
3232
}
3333
},
3434
"scripts": {
35-
"build": "rollup --bundleConfigAsCjs --config rollup.config.js --compact --environment BUILD:production && node ./scripts/build.js",
36-
"watch": "rollup --bundleConfigAsCjs --config rollup.config.js -w",
37-
"format:check": "prettier --end-of-line auto --cache --check \"**/*.{ts,js}\"",
38-
"format:fix": "prettier --cache --write \"**/*.{ts,js}\"",
35+
"build": "vite build && node ./scripts/build.js",
36+
"watch": "vite build -w",
37+
"format:check": "prettier --end-of-line auto --cache --check \"{src,types,scripts}/**/*.{ts,js}\"",
38+
"format:fix": "prettier --cache --write \"{src,types,scripts}/**/*.{ts,js}\"",
3939
"lint:clean": "rimraf .eslintcache",
4040
"lint:fix": "node --max-old-space-size=6144 node_modules/eslint/bin/eslint.js --cache . --fix --ext js,ts",
4141
"lint:check": "node --max-old-space-size=6144 node_modules/eslint/bin/eslint.js --cache . --ext js,ts",
4242
"test": "vitest run --coverage",
4343
"test:all": "npm run test && npm run test:e2e",
4444
"test:e2e:setup": "xvfb-maybe --auto-servernum --server-args='-screen 0 1280x960x24' --",
4545
"test:e2e": "cross-env E2E_TESTS=true npm run test:e2e:setup vitest run tests/src/ --pool=threads --poolOptions.threads.singleThread --poolOptions.threads.isolate --no-file-parallelism"
46-
4746
},
4847
"dependencies": {
4948
"@podman-desktop/api": "^1.10.0",
5049
"@redhat-developer/rhcra-client": "^0.0.1",
5150
"@redhat-developer/rhsm-client": "^0.0.4",
5251
"axios": "^1.6.5",
5352
"js-yaml": "^4.1.0",
54-
"openid-client": "5.4.0"
53+
"openid-client": "^5.6.5"
5554
},
5655
"devDependencies": {
5756
"7zip-min": "^1.4.3",
58-
"@rollup/plugin-commonjs": "^24.0.1",
59-
"@rollup/plugin-json": "^6.0.0",
60-
"@rollup/plugin-node-resolve": "^15.0.2",
61-
"@rollup/plugin-typescript": "^11.1.0",
57+
"@playwright/test": "^1.42.1",
58+
"@podman-desktop/tests-playwright": "next",
6259
"@types/js-yaml": "^4.0.5",
6360
"@types/node": "^20",
6461
"@typescript-eslint/eslint-plugin": "^7.0.0",
6562
"@typescript-eslint/parser": "^6.21.0",
66-
"@playwright/test": "^1.42.1",
67-
"@podman-desktop/tests-playwright": "next",
6863
"@vitest/coverage-v8": "^1.2.1",
64+
"byline": "^5.0.0",
65+
"copyfiles": "^2.4.1",
6966
"cross-env": "7.0.3",
7067
"electron": "^29.1.4",
7168
"eslint": "^8.57.0",
@@ -81,10 +78,9 @@
8178
"eslint-plugin-unicorn": "^51.0.1",
8279
"mkdirp": "^2.1.3",
8380
"prettier": "^3.2.5",
84-
"rollup": "^3.20.4",
8581
"tslib": "^2.5.0",
8682
"typescript": "^5.0.4",
87-
"vite": "^5.0.12",
83+
"vite": "^5.2.12",
8884
"vitest": "^1.4.0",
8985
"xvfb-maybe": "^0.2.1",
9086
"zip-local": "^0.3.5"

scripts/build.js

+36-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env node
22
/**********************************************************************
3-
* Copyright (C) 2022 Red Hat, Inc.
3+
* Copyright (C) 2022 - 2024 Red Hat, Inc.
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
66
* you may not use this file except in compliance with the License.
@@ -22,10 +22,18 @@ const path = require('path');
2222
const package = require('../package.json');
2323
const { mkdirp } = require('mkdirp');
2424
const fs = require('fs');
25+
const byline = require('byline');
26+
const cp = require('copyfiles');
27+
const cproc = require('node:child_process');
2528

2629
const destFile = path.resolve(__dirname, `../${package.name}.cdix`);
2730
const builtinDirectory = path.resolve(__dirname, '../builtin');
28-
const unzippedDirectory = path.resolve(builtinDirectory, `${package.name}.cdix`);
31+
const zipDirectory = path.resolve(builtinDirectory, `${package.name}.cdix`);
32+
const extFiles = path.resolve(__dirname, '../.extfiles');
33+
const fileStream = fs.createReadStream(extFiles, { encoding: 'utf8' });
34+
35+
const includedFiles = [];
36+
2937
// remove the .cdix file before zipping
3038
if (fs.existsSync(destFile)) {
3139
fs.rmSync(destFile);
@@ -35,9 +43,31 @@ if (fs.existsSync(builtinDirectory)) {
3543
fs.rmSync(builtinDirectory, { recursive: true, force: true });
3644
}
3745

38-
zipper.sync.zip(path.resolve(__dirname, '../')).compress().save(destFile);
46+
// install external modules into dist folder
47+
cproc.exec('yarn add [email protected] --cwd .', { cwd: './dist' }, (error, stdout, stderr) => {
48+
if (error) {
49+
console.log(stdout);
50+
console.log(stderr);
51+
throw error;
52+
}
3953

40-
// create unzipped built-in
41-
mkdirp(unzippedDirectory).then(() => {
42-
zipper.sync.unzip(destFile).save(unzippedDirectory);
54+
byline(fileStream)
55+
.on('data', line => {
56+
includedFiles.push(line);
57+
})
58+
.on('error', () => {
59+
throw new Error('Error reading .extfiles');
60+
})
61+
.on('end', () => {
62+
includedFiles.push(zipDirectory); // add destination dir
63+
mkdirp.sync(zipDirectory);
64+
console.log(`Copying files to ${zipDirectory}`);
65+
cp(includedFiles, error => {
66+
if (error) {
67+
throw new Error('Error copying files', error);
68+
}
69+
console.log(`Zipping files to ${destFile}`);
70+
zipper.sync.zip(zipDirectory).compress().save(destFile);
71+
});
72+
});
4373
});

tests/src/setupFiles/extended-hooks.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
* SPDX-License-Identifier: Apache-2.0
1717
***********************************************************************/
1818

19-
import { type RunnerTestContext, takeScreenshotHook } from '@podman-desktop/tests-playwright';
19+
import { type RunnerTestContext,takeScreenshotHook } from '@podman-desktop/tests-playwright';
2020
import { afterEach } from 'vitest';
2121

2222
afterEach(async (context: RunnerTestContext) => {

tests/src/sso-extension.spec.ts

+10-20
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,11 @@
1515
*
1616
* SPDX-License-Identifier: Apache-2.0
1717
***********************************************************************/
18-
import type { Page } from '@playwright/test';
18+
import type { Page} from '@playwright/test';
1919
import { expect as playExpect } from '@playwright/test';
20-
import type { RunnerTestContext } from '@podman-desktop/tests-playwright';
21-
import {
22-
AuthenticationPage,
23-
ExtensionCardPage,
24-
NavigationBar,
25-
PodmanDesktopRunner,
26-
WelcomePage,
27-
} from '@podman-desktop/tests-playwright';
28-
import { afterAll, beforeAll, beforeEach, describe, test } from 'vitest';
20+
import type { RunnerTestContext} from '@podman-desktop/tests-playwright';
21+
import { AuthenticationPage, ExtensionCardPage, NavigationBar, PodmanDesktopRunner, WelcomePage } from '@podman-desktop/tests-playwright';
22+
import { afterAll, beforeAll, beforeEach,describe, test } from 'vitest';
2923

3024
import { SSOExtensionPage } from './model/pages/sso-extension-page';
3125

@@ -41,6 +35,7 @@ const authProviderName = 'Red Hat SSO';
4135
const activeExtensionStatus = 'ACTIVE';
4236
const disabledExtensionStatus = 'DISABLED';
4337

38+
4439
beforeEach<RunnerTestContext>(async ctx => {
4540
ctx.pdRunner = pdRunner;
4641
});
@@ -61,6 +56,7 @@ afterAll(async () => {
6156
});
6257

6358
describe('Red Hat Authentication extension verification', async () => {
59+
6460
test('Go to extensions and check if extension is already installed', async () => {
6561
const extensions = await navBar.openExtensions();
6662
if (await extensions.extensionIsInstalled(extensionLabel)) {
@@ -103,12 +99,8 @@ describe('Red Hat Authentication extension verification', async () => {
10399
const authPage = await settingsBar.openTabPage(AuthenticationPage);
104100
await playExpect(authPage.heading).toHaveText('Authentication');
105101
const provider = authPage.getProvider(authProviderName);
106-
await playExpect(provider.getByLabel('Provider Information').getByLabel('Provider Name')).toHaveText(
107-
authProviderName,
108-
);
109-
await playExpect(provider.getByLabel('Provider Information').getByLabel('Provider Status')).toHaveText(
110-
'Logged out',
111-
);
102+
await playExpect(provider.getByLabel('Provider Information').getByLabel('Provider Name')).toHaveText(authProviderName);
103+
await playExpect(provider.getByLabel('Provider Information').getByLabel('Provider Status')).toHaveText('Logged out');
112104
await playExpect(provider.getByLabel('Provider Actions').getByRole('button')).toContainText('Sign in');
113105
});
114106

@@ -140,7 +132,7 @@ describe('Red Hat Authentication extension verification', async () => {
140132
const authPage = await settingsBar.openTabPage(AuthenticationPage);
141133
await playExpect(authPage.heading).toHaveText('Authentication');
142134
await playExpect(authPage.getProvider(authProviderName)).toHaveCount(1);
143-
});
135+
});
144136
});
145137

146138
test('SSO extension can be removed', async () => {
@@ -153,7 +145,5 @@ async function removeExtension(): Promise<void> {
153145
const extensionCard = await extensions.getInstalledExtension(extensionLabelName, extensionLabel);
154146
await extensionCard.disableExtension();
155147
await extensionCard.removeExtension();
156-
await playExpect
157-
.poll(async () => await extensions.extensionIsInstalled(extensionLabel), { timeout: 15000 })
158-
.toBeFalsy();
148+
await playExpect.poll(async () => await extensions.extensionIsInstalled(extensionLabel), { timeout: 15000 }).toBeFalsy();
159149
}

vite.config.js

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/**********************************************************************
2+
* Copyright (C) 2023 Red Hat, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* SPDX-License-Identifier: Apache-2.0
17+
***********************************************************************/
18+
19+
import { join } from 'path';
20+
import { builtinModules } from 'module';
21+
22+
const PACKAGE_ROOT = __dirname;
23+
24+
/**
25+
* @type {import('vite').UserConfig}
26+
* @see https://vitejs.dev/config/
27+
*/
28+
const config = {
29+
mode: process.env.MODE,
30+
root: PACKAGE_ROOT,
31+
envDir: process.cwd(),
32+
resolve: {
33+
alias: {
34+
'/@/': join(PACKAGE_ROOT, 'src') + '/',
35+
},
36+
},
37+
optimizeDeps: {},
38+
build: {
39+
sourcemap: 'inline',
40+
target: 'esnext',
41+
outDir: 'dist',
42+
assetsDir: '.',
43+
minify: process.env.MODE === 'production' ? 'esbuild' : false,
44+
lib: {
45+
entry: 'src/extension.ts',
46+
formats: ['cjs'],
47+
},
48+
rollupOptions: {
49+
external: [
50+
'@podman-desktop/api',
51+
'object-hash', // has to be external because of browser entry in package.json
52+
...builtinModules.flatMap(p => [p, `node:${p}`]),
53+
],
54+
output: {
55+
entryFileNames: '[name].cjs',
56+
intro: 'const window = {}',
57+
},
58+
},
59+
emptyOutDir: true,
60+
reportCompressedSize: false,
61+
},
62+
};
63+
64+
export default config;

vitest.config.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ const excludeArray = [
3737
];
3838

3939
export function coverageConfig(packageRoot, packageName) {
40-
const obj = {
41-
coverage: {
40+
const obj = { coverage: {
4241
all: true,
4342
clean: true,
4443
src: [packageRoot],

0 commit comments

Comments
 (0)