feat: Initial clean release of CHM
一些检查失败了
automerge / automerge (push) Has been cancelled
react-native-android-build-apk / AssembleRelease (push) Has been cancelled
Build macOS M1 / Main (push) Has been cancelled
Joplin Continuous Integration / Main (macos-15-intel) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-11-vs2026-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-2025) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04-arm) (push) Has been cancelled
Joplin UI tests / Main (ubuntu-22.04) (push) Has been cancelled
Joplin UI tests / Main (windows-2025) (push) Has been cancelled
Joplin UI tests / Mobile (push) Has been cancelled
Close stale issues / ProcessStaleIssues (push) Has been cancelled
一些检查失败了
automerge / automerge (push) Has been cancelled
react-native-android-build-apk / AssembleRelease (push) Has been cancelled
Build macOS M1 / Main (push) Has been cancelled
Joplin Continuous Integration / Main (macos-15-intel) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-11-vs2026-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-2025) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04-arm) (push) Has been cancelled
Joplin UI tests / Main (ubuntu-22.04) (push) Has been cancelled
Joplin UI tests / Main (windows-2025) (push) Has been cancelled
Joplin UI tests / Mobile (push) Has been cancelled
Close stale issues / ProcessStaleIssues (push) Has been cancelled
这个提交包含在:
@@ -0,0 +1,127 @@
|
||||
// React Native WebView cannot load external JS files, however it can load
|
||||
// arbitrary JS via the injectedJavaScript property. So we use this to load external
|
||||
// files: First here we convert the JS file to a plain string, and that string
|
||||
// is then loaded by eg. the Mermaid plugin, and finally injected in the WebView.
|
||||
|
||||
import { dirname, extname, basename, resolve } from 'path';
|
||||
|
||||
import * as esbuild from 'esbuild';
|
||||
import copyAssets from './copyAssets';
|
||||
import { writeFile, readFile } from 'fs-extra';
|
||||
|
||||
export default class BundledFile {
|
||||
private readonly bundleOutputPathBase_: string;
|
||||
private readonly bundleBaseName_: string;
|
||||
private readonly rootFileDirectory_: string;
|
||||
|
||||
public constructor(
|
||||
public readonly bundleName: string,
|
||||
private readonly sourceFilePath_: string,
|
||||
) {
|
||||
this.rootFileDirectory_ = dirname(sourceFilePath_);
|
||||
this.bundleBaseName_ = basename(sourceFilePath_, extname(sourceFilePath_));
|
||||
this.bundleOutputPathBase_ = `${this.rootFileDirectory_}/${this.bundleBaseName_}.bundle`;
|
||||
}
|
||||
|
||||
private makeBuildContext(mode: 'production' | 'development') {
|
||||
return esbuild.context({
|
||||
entryPoints: [this.sourceFilePath_],
|
||||
outfile: `${this.bundleOutputPathBase_}.js`,
|
||||
minify: mode === 'production',
|
||||
bundle: true,
|
||||
sourcemap: true,
|
||||
format: 'iife',
|
||||
globalName: this.bundleName,
|
||||
metafile: false,
|
||||
|
||||
// es5: Have Webpack's generated code target ES5. This doesn't apply to code not
|
||||
// generated by Webpack.
|
||||
target: ['chrome58', 'safari14'],
|
||||
|
||||
plugins: [
|
||||
{
|
||||
name: 'joplin--node-polyfills',
|
||||
setup: build => {
|
||||
build.onResolve({ filter: /^(path|events)$/ }, args => {
|
||||
let path = args.path;
|
||||
if (args.path === 'path') {
|
||||
path = require.resolve('path-browserify');
|
||||
} else if (args.path === 'events') {
|
||||
path = require.resolve('events/');
|
||||
}
|
||||
|
||||
return { path };
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
// Supports require(...)ing SVG images
|
||||
name: 'joplin--require-svg',
|
||||
setup: build => {
|
||||
// A relative path to an SVG:
|
||||
build.onResolve({ filter: /^\.{1,2}\/.*\.svg$/ }, args => ({
|
||||
path: resolve(args.resolveDir, args.path),
|
||||
namespace: 'joplin-require-svg',
|
||||
}));
|
||||
|
||||
build.onLoad({ filter: /^.*$/, namespace: 'joplin-require-svg' }, async args => {
|
||||
const fileContent = await readFile(args.path, 'utf-8');
|
||||
return { contents: `
|
||||
let svg = null;
|
||||
export default () => {
|
||||
svg ??= (() => {
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(${JSON.stringify(fileContent)}, 'image/svg+xml');
|
||||
return doc.querySelector('svg');
|
||||
})();
|
||||
return svg.cloneNode(true);
|
||||
};
|
||||
` };
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'joplin--copy-final',
|
||||
setup: build => {
|
||||
build.onEnd(async (result) => {
|
||||
if (result.errors.length === 0) {
|
||||
console.log('copy output');
|
||||
await this.copyToImportableFile_();
|
||||
} else {
|
||||
console.warn('Copying skipped. Build produced errors');
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// Creates a file that can be imported by React native. This file contains the
|
||||
// bundled JS as a string.
|
||||
private async copyToImportableFile_() {
|
||||
await copyAssets(`${this.bundleName}.bundle`, {
|
||||
js: `${this.bundleOutputPathBase_}.js`,
|
||||
css: `${this.bundleOutputPathBase_}.css`,
|
||||
});
|
||||
}
|
||||
|
||||
// Create a minified JS file in the same directory as `this.sourceFilePath` with
|
||||
// the same name.
|
||||
public async build() {
|
||||
console.info(`Building bundle: ${this.bundleName}...`);
|
||||
const compiler = await this.makeBuildContext('production');
|
||||
const result = await compiler.rebuild();
|
||||
await compiler.dispose();
|
||||
|
||||
if (result?.metafile) {
|
||||
await writeFile(`${this.bundleOutputPathBase_}.meta.json`, JSON.stringify(result.metafile, undefined, '\t'));
|
||||
}
|
||||
}
|
||||
|
||||
public async startWatching() {
|
||||
console.info(`Watching bundle: ${this.bundleName}...`);
|
||||
const compiler = await this.makeBuildContext('development');
|
||||
await compiler.watch();
|
||||
}
|
||||
}
|
||||
在新工单中引用
屏蔽一个用户