Skip to content

Commit 1068bf5

Browse files
authored
special-pages: integrated watch mode (#1317)
* special-pages: integrated watch mode * special-pages dev workflow * fixed docs * fixing * fixed locale path
1 parent 617638c commit 1068bf5

File tree

365 files changed

+442
-194
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

365 files changed

+442
-194
lines changed

package-lock.json

Lines changed: 31 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

special-pages/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
test-results
22
playwright-report
3+
pages/**/public/dist
4+
/timestamp.json

special-pages/index.mjs

Lines changed: 17 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { existsSync, cpSync, rmSync, readFileSync, writeFileSync } from 'node:fs
88
import { buildSync } from 'esbuild';
99
import { cwd, parseArgs } from '../scripts/script-utils.js';
1010
import inliner from 'web-resource-inliner';
11+
import { baseEsbuildOptions } from './opts.mjs';
1112

1213
const CWD = cwd(import.meta.url);
1314
const ROOT = join(CWD, '../');
@@ -58,19 +59,19 @@ export const support = {
5859
},
5960
};
6061

61-
/** @type {{src: string, dest: string, injectName: string}[]} */
62+
/** @type {{src: string, dest: string, dist: string, injectName: string}[]} */
6263
const copyJobs = [];
63-
/** @type {{entryPoints: string[], outputDir: string, injectName: string, pageName: string}[]} */
64+
/** @type {{outputDir: string, injectName: ImportMeta['injectName'], pageName: string}[]} */
6465
const buildJobs = [];
6566
/** @type {{src: string}[]} */
6667
const inlineJobs = [];
6768
const errors = [];
6869
const DRY_RUN = false;
6970

7071
for (const [pageName, injectNames] of Object.entries(support)) {
71-
const pageSrc = join(CWD, 'pages', pageName, 'src');
72-
if (!existsSync(pageSrc)) {
73-
errors.push(`${pageSrc} does not exist. Each page must have a 'src' directory`);
72+
const publicDir = join(CWD, 'pages', pageName, 'public');
73+
if (!existsSync(publicDir)) {
74+
errors.push(`${publicDir} does not exist. Each page must have a 'src' directory`);
7475
continue;
7576
}
7677
for (const [injectName, jobs] of Object.entries(injectNames)) {
@@ -82,20 +83,17 @@ for (const [pageName, injectNames] of Object.entries(support)) {
8283
for (const job of jobs) {
8384
if (job === 'copy') {
8485
copyJobs.push({
85-
src: pageSrc,
86+
src: publicDir,
87+
dist: join(publicDir, 'dist'),
8688
dest: pageOutputDirectory,
8789
injectName,
8890
});
8991
}
9092
if (job === 'build-js') {
91-
const entryPoints = [join(pageSrc, 'js', 'index.js'), join(pageSrc, 'js', 'inline.js')].filter((pathname) =>
92-
existsSync(pathname),
93-
);
94-
const outputDir = join(pageOutputDirectory, 'js');
93+
const outputDir = join(pageOutputDirectory, 'dist');
9594
buildJobs.push({
96-
entryPoints,
9795
outputDir,
98-
injectName,
96+
injectName: /** @type {ImportMeta['injectName']} */ (injectName),
9997
pageName,
10098
});
10199
}
@@ -118,6 +116,10 @@ if (errors.length > 0) {
118116
for (const copyJob of copyJobs) {
119117
if (DEBUG) console.log('COPY:', relative(ROOT, copyJob.src), relative(ROOT, copyJob.dest));
120118
if (!DRY_RUN) {
119+
rmSync(copyJob.dist, {
120+
force: true,
121+
recursive: true,
122+
});
121123
rmSync(copyJob.dest, {
122124
force: true,
123125
recursive: true,
@@ -129,40 +131,12 @@ for (const copyJob of copyJobs) {
129131
}
130132
}
131133
for (const buildJob of buildJobs) {
132-
if (DEBUG) console.log('BUILD:', buildJob.entryPoints, relative(ROOT, buildJob.outputDir));
134+
if (DEBUG) console.log('BUILD:', buildJob);
133135
if (DEBUG) console.log('\t- import.meta.env: ', NODE_ENV);
134136
if (DEBUG) console.log('\t- import.meta.injectName: ', buildJob.injectName);
135137
if (!DRY_RUN) {
136-
const output = buildSync({
137-
entryPoints: buildJob.entryPoints,
138-
outdir: buildJob.outputDir,
139-
bundle: true,
140-
// metafile: true,
141-
// minify: true,
142-
// splitting: true,
143-
// external: ['../assets/img/*'],
144-
format: 'iife',
145-
sourcemap: NODE_ENV === 'development',
146-
loader: {
147-
'.js': 'jsx',
148-
'.module.css': 'local-css',
149-
'.svg': 'file',
150-
'.data.svg': 'dataurl',
151-
'.jpg': 'file',
152-
'.png': 'file',
153-
'.riv': 'file',
154-
},
155-
define: {
156-
'import.meta.env': JSON.stringify(NODE_ENV),
157-
'import.meta.injectName': JSON.stringify(buildJob.injectName),
158-
'import.meta.pageName': JSON.stringify(buildJob.pageName),
159-
},
160-
dropLabels: buildJob.injectName === 'integration' ? [] : ['$INTEGRATION'],
161-
});
162-
if (output.metafile) {
163-
const meta = JSON.stringify(output.metafile, null, 2);
164-
writeFileSync(join(buildJob.outputDir, 'metafile.json'), meta);
165-
}
138+
const opts = baseEsbuildOptions(buildJob.pageName, buildJob.injectName, NODE_ENV, buildJob.outputDir);
139+
buildSync(opts);
166140
}
167141
}
168142
for (const inlineJob of inlineJobs) {

special-pages/opts.mjs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { join } from 'node:path';
2+
import { cwd } from '../scripts/script-utils.js';
3+
const CWD = cwd(import.meta.url);
4+
5+
/**
6+
* @param {string} page
7+
* @param {ImportMeta['injectName']} injectName
8+
* @param {'development' | 'production'} nodeEnv
9+
* @param {string} [output] - optionally change the output folder
10+
* @return {import('esbuild').BuildOptions}
11+
*/
12+
export function baseEsbuildOptions(page, injectName, nodeEnv, output) {
13+
const pageDir = join(CWD, 'pages', page);
14+
const publicDir = join(pageDir, 'public');
15+
const srcDir = join(pageDir, 'src');
16+
const distDir = output || join(publicDir, 'dist');
17+
const entry = [join(srcDir, 'index.js'), join(srcDir, 'inline.js')];
18+
return {
19+
entryPoints: entry,
20+
outdir: distDir,
21+
bundle: true,
22+
format: 'iife',
23+
sourcemap: nodeEnv === 'development',
24+
loader: {
25+
'.js': 'jsx',
26+
'.module.css': 'local-css',
27+
'.svg': 'file',
28+
'.data.svg': 'dataurl',
29+
'.jpg': 'file',
30+
'.png': 'file',
31+
'.riv': 'file',
32+
'.txt': 'file',
33+
},
34+
define: {
35+
'import.meta.env': JSON.stringify(nodeEnv),
36+
'import.meta.injectName': JSON.stringify(injectName),
37+
'import.meta.pageName': JSON.stringify(page),
38+
},
39+
// prettier-ignore
40+
dropLabels: injectName === 'integration'
41+
? ['$WATCH']
42+
: ['$WATCH', '$INTEGRATION'],
43+
};
44+
}

special-pages/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,16 @@
2020
"test.headed": "npm run test-int -- --headed",
2121
"test.ui": "npm run test-int -- --ui",
2222
"serve": "http-server -c-1 --port 3210 ../build/integration/pages",
23-
"watch": "chokidar pages shared --initial -c 'npm run build.dev' --ignore 'pages/**/locales' --ignore 'pages/**/types'"
23+
"watch": "node watch.mjs"
2424
},
2525
"license": "ISC",
2626
"devDependencies": {
2727
"@duckduckgo/messaging": "*",
2828
"esbuild": "^0.24.0",
2929
"http-server": "^14.1.1",
3030
"web-resource-inliner": "^6.0.1",
31-
"fast-check": "^3.23.1"
31+
"fast-check": "^3.23.1",
32+
"chokidar": "^4.0.1"
3233
},
3334
"dependencies": {
3435
"preact": "^10.24.3",

special-pages/pages/duckplayer/app/features/click-capture.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* @typedef {import("./iframe").IframeFeature} IframeFeature
33
*/
44

5-
import { createYoutubeURLForError } from '../../src/js/utils.js';
5+
import { createYoutubeURLForError } from '../../src/utils.js';
66

77
/**
88
* @implements IframeFeature

special-pages/pages/duckplayer/app/features/title-capture.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
* @typedef {import("./iframe").IframeFeature} IframeFeature
33
*/
4-
import { getValidVideoTitle } from '../../src/js/utils.js';
4+
import { getValidVideoTitle } from '../../src/utils.js';
55

66
/**
77
* @implements IframeFeature

special-pages/pages/duckplayer/app/index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { EnvironmentProvider, UpdateEnvironment, WillThrow } from '../../../shar
55
import { TranslationProvider } from '../../../shared/components/TranslationsProvider.js';
66
import { ErrorBoundary } from '../../../shared/components/ErrorBoundary.js';
77
import { EmbedSettings } from './embed-settings.js';
8-
import enStrings from '../src/locales/en/duckplayer.json';
8+
import enStrings from '../public/locales/en/duckplayer.json';
99
import { Settings } from './settings.js';
1010
import { SettingsProvider } from './providers/SettingsProvider.jsx';
1111
import { MessagingContext, TelemetryContext } from './types.js';
@@ -16,8 +16,8 @@ import { MobileApp } from './components/MobileApp.jsx';
1616
import { DesktopApp } from './components/DesktopApp.jsx';
1717

1818
/**
19-
* @param {import("../src/js/index.js").DuckplayerPage} messaging
20-
* @param {import("../src/js/index.js").Telemetry} telemetry
19+
* @param {import("../src/index.js").DuckplayerPage} messaging
20+
* @param {import("../src/index.js").Telemetry} telemetry
2121
* @param {import("../../../shared/environment").Environment} baseEnvironment
2222
* @return {Promise<void>}
2323
*/

special-pages/pages/duckplayer/app/types.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useContext } from 'preact/hooks';
22
import { TranslationContext } from '../../../shared/components/TranslationsProvider.js';
33
// eslint-disable-next-line @typescript-eslint/no-unused-vars
4-
import json from '../src/locales/en/duckplayer.json';
4+
import json from '../public/locales/en/duckplayer.json';
55
import { createContext } from 'preact';
66

77
/**
@@ -14,7 +14,7 @@ export function useTypedTranslation() {
1414
};
1515
}
1616

17-
export const MessagingContext = createContext(/** @type {import("../src/js/index.js").DuckplayerPage} */ ({}));
17+
export const MessagingContext = createContext(/** @type {import("../src/index.js").DuckplayerPage} */ ({}));
1818
export const useMessaging = () => useContext(MessagingContext);
19-
export const TelemetryContext = createContext(/** @type {import("../src/js/index.js").Telemetry} */ ({}));
19+
export const TelemetryContext = createContext(/** @type {import("../src/index.js").Telemetry} */ ({}));
2020
export const useTelemetry = () => useContext(TelemetryContext);

special-pages/pages/duckplayer/src/index.html renamed to special-pages/pages/duckplayer/public/index.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
<title>Duck Player</title>
55
<meta name="robots" content="noindex,nofollow">
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7-
<script src="js/inline.js"></script>
8-
<link rel="stylesheet" href="./js/index.css" />
7+
<script src="./dist/inline.js"></script>
8+
<link rel="stylesheet" href="./dist/index.css" />
99
</head>
1010
<body>
1111
<div id="app"></div>
12-
<script type="module" src="js/index.js"></script>
12+
<script type="module" src="./dist/index.js"></script>
1313
</body>
1414
</html>

0 commit comments

Comments
 (0)