1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-01-02 12:47:41 +02:00

Tools: Fixes #5902: Correctly load external resources when bundling desktop app

This commit is contained in:
Laurent Cozic 2021-12-23 12:04:09 +01:00
parent e65d06fbf5
commit 9ca298f500
14 changed files with 52 additions and 28 deletions

View File

@ -248,7 +248,9 @@
"packages/app-desktop/**/node_modules/": true, "packages/app-desktop/**/node_modules/": true,
"packages/app-desktop/**/packageInfo.js": true, "packages/app-desktop/**/packageInfo.js": true,
"packages/app-desktop/**/pluginAssets/": true, "packages/app-desktop/**/pluginAssets/": true,
"packages/app-desktop/build/": true, "packages/app-desktop/build/icons/": true,
"packages/app-desktop/build/images/": true,
"packages/app-desktop/vendor/lib/": true,
"packages/app-desktop/dist/": true, "packages/app-desktop/dist/": true,
"packages/app-desktop/fonts/": true, "packages/app-desktop/fonts/": true,
"packages/app-desktop/gui/note-viewer/highlight/styles/": true, "packages/app-desktop/gui/note-viewer/highlight/styles/": true,

View File

@ -11,4 +11,6 @@ gui/NoteEditor/NoteBody/TinyMCE/supportedLocales.js
runForSharingCommands-* runForSharingCommands-*
runForTestingCommands-* runForTestingCommands-*
style.min.css style.min.css
build/lib/ build/lib/
vendor/
!vendor/loadEmojiLib.js

View File

@ -34,6 +34,29 @@ export class Bridge {
return !this.electronApp().electronApp().isPackaged; return !this.electronApp().electronApp().isPackaged;
} }
// The build directory contains additional external files that are going to
// be packaged by Electron Builder. This is for files that need to be
// accessed outside of the Electron app (for example the application icon).
//
// Any static file that's accessed from within the app such as CSS or fonts
// should go in /vendor.
//
// The build folder location is dynamic, depending on whether we're running
// in dev or prod, which makes it hard to access it from static files (for
// example from plain HTML files that load CSS or JS files). For this reason
// it should be avoided as much as possible.
public buildDir() {
return this.electronApp().buildDir();
}
// The vendor directory and its content is dynamically created from other
// dir (usually by pulling files from node_modules). It can also be accessed
// using a relative path such as "../../vendor/lib/file.js" because it will
// be at the same location in both prod and dev mode (unlike the build dir).
public vendorDir() {
return `${__dirname}/vendor`;
}
env() { env() {
return this.electronWrapper_.env(); return this.electronWrapper_.env();
} }
@ -223,10 +246,6 @@ export class Bridge {
return require('electron').shell.openPath(fullPath); return require('electron').shell.openPath(fullPath);
} }
buildDir() {
return this.electronApp().buildDir();
}
screen() { screen() {
return require('electron').screen; return require('electron').screen;
} }

View File

@ -4,6 +4,7 @@ import useAsyncEffect, { AsyncEffectEvent } from '@joplin/lib/hooks/useAsyncEffe
import { loadScript } from '../utils/loadScript'; import { loadScript } from '../utils/loadScript';
import Button from '../Button/Button'; import Button from '../Button/Button';
import { FolderIcon } from '@joplin/lib/services/database/types'; import { FolderIcon } from '@joplin/lib/services/database/types';
import bridge from '../../services/bridge';
export interface ChangeEvent { export interface ChangeEvent {
value: FolderIcon; value: FolderIcon;
@ -29,7 +30,7 @@ export const IconSelector = (props: Props) => {
await loadScript({ await loadScript({
id: 'emoji-button-lib', id: 'emoji-button-lib',
src: 'build/lib/@joeattardi/emoji-button/dist/index.js', src: `${bridge().vendorDir()}/lib/@joeattardi/emoji-button/dist/index.js`,
attrs: { attrs: {
type: 'module', type: 'module',
}, },
@ -39,7 +40,7 @@ export const IconSelector = (props: Props) => {
await loadScript({ await loadScript({
id: 'emoji-button-lib-loader', id: 'emoji-button-lib-loader',
src: 'gui/EditFolderDialog/loadEmojiLib.js', src: `${bridge().vendorDir()}/loadEmojiLib.js`,
attrs: { attrs: {
type: 'module', type: 'module',
}, },

View File

@ -1,2 +0,0 @@
import { EmojiButton } from '../../build/lib/@joeattardi/emoji-button/dist/index.js';
window.EmojiButton = EmojiButton;

View File

@ -336,7 +336,7 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) {
async function loadScripts() { async function loadScripts() {
const scriptsToLoad: {src: string; id: string; loaded: boolean}[] = [ const scriptsToLoad: {src: string; id: string; loaded: boolean}[] = [
{ {
src: 'build/lib/codemirror/addon/dialog/dialog.css', src: `${bridge().vendorDir()}/lib/codemirror/addon/dialog/dialog.css`,
id: 'codemirrorDialogStyle', id: 'codemirrorDialogStyle',
loaded: false, loaded: false,
}, },
@ -351,7 +351,7 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) {
if (theme.indexOf('solarized') >= 0) theme = 'solarized'; if (theme.indexOf('solarized') >= 0) theme = 'solarized';
scriptsToLoad.push({ scriptsToLoad.push({
src: `build/lib/codemirror/theme/${theme}.css`, src: `${bridge().vendorDir()}/lib/codemirror/theme/${theme}.css`,
id: `codemirrorTheme${theme}`, id: `codemirrorTheme${theme}`,
loaded: false, loaded: false,
}); });

View File

@ -23,6 +23,7 @@ import openEditDialog from './utils/openEditDialog';
import { MarkupToHtmlOptions } from '../../utils/useMarkupToHtml'; import { MarkupToHtmlOptions } from '../../utils/useMarkupToHtml';
import { themeStyle } from '@joplin/lib/theme'; import { themeStyle } from '@joplin/lib/theme';
import { loadScript } from '../../../utils/loadScript'; import { loadScript } from '../../../utils/loadScript';
import bridge from '../../../../services/bridge';
const { clipboard } = require('electron'); const { clipboard } = require('electron');
const supportedLocales = require('./supportedLocales'); const supportedLocales = require('./supportedLocales');
@ -320,7 +321,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
async function loadScripts() { async function loadScripts() {
const scriptsToLoad: any[] = [ const scriptsToLoad: any[] = [
{ {
src: 'build/lib/tinymce/tinymce.min.js', src: `${bridge().vendorDir()}/lib/tinymce/tinymce.min.js`,
id: 'tinyMceScript', id: 'tinyMceScript',
loaded: false, loaded: false,
}, },
@ -571,7 +572,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
statusbar: false, statusbar: false,
target_list: false, target_list: false,
table_resize_bars: false, table_resize_bars: false,
language_url: ['en_US', 'en_GB'].includes(language) ? undefined : `build/lib/tinymce/langs/${language}`, language_url: ['en_US', 'en_GB'].includes(language) ? undefined : `${bridge().vendorDir()}/lib/tinymce/langs/${language}`,
toolbar: toolbar.join(' '), toolbar: toolbar.join(' '),
localization_function: _, localization_function: _,
contextmenu: false, contextmenu: false,
@ -708,7 +709,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
} }
const cssFiles = [ const cssFiles = [
'build/lib/@fortawesome/fontawesome-free/css/all.min.css', `${bridge().vendorDir()}/lib/@fortawesome/fontawesome-free/css/all.min.css`,
`gui/note-viewer/pluginAssets/highlight.js/${theme.codeThemeCss}`, `gui/note-viewer/pluginAssets/highlight.js/${theme.codeThemeCss}`,
].concat( ].concat(
pluginAssets pluginAssets

View File

@ -430,7 +430,7 @@
setMarkers(markLoader_.whenDone.keywords, markLoader_.whenDone.options); setMarkers(markLoader_.whenDone.keywords, markLoader_.whenDone.options);
}; };
script.src = '../../build/lib/mark.js/dist/mark.min.js'; script.src = '../../vendor/lib/mark.js/dist/mark.min.js';
document.getElementById('joplin-container-markScriptContainer').appendChild(script); document.getElementById('joplin-container-markScriptContainer').appendChild(script);
} else if (markLoader_.state === 'ready') { } else if (markLoader_.state === 'ready') {
setMarkers(keywords, options); setMarkers(keywords, options);

View File

@ -10,6 +10,8 @@ export interface Script {
export const loadScript = async (script: Script) => { export const loadScript = async (script: Script) => {
return new Promise((resolve) => { return new Promise((resolve) => {
console.info('Loading script:', script);
let element: any = document.getElementById(script.id); let element: any = document.getElementById(script.id);
if (element) { if (element) {

View File

@ -10,11 +10,11 @@
<title>Joplin</title> <title>Joplin</title>
<link rel="stylesheet" href="style.min.css"> <link rel="stylesheet" href="style.min.css">
<link rel="stylesheet" href="style/icons/style.css"> <link rel="stylesheet" href="style/icons/style.css">
<link rel="stylesheet" href="build/lib/@fortawesome/fontawesome-free/css/all.min.css"> <link rel="stylesheet" href="vendor/lib/@fortawesome/fontawesome-free/css/all.min.css">
<link rel="stylesheet" href="build/lib/react-datetime/css/react-datetime.css"> <link rel="stylesheet" href="vendor/lib/react-datetime/css/react-datetime.css">
<link rel="stylesheet" href="build/lib/smalltalk/css/smalltalk.css"> <link rel="stylesheet" href="vendor/lib/smalltalk/css/smalltalk.css">
<link rel="stylesheet" href="build/lib/roboto-fontface/css/roboto/roboto-fontface.css"> <link rel="stylesheet" href="vendor/lib/roboto-fontface/css/roboto/roboto-fontface.css">
<link rel="stylesheet" href="build/lib/codemirror/lib/codemirror.css"> <link rel="stylesheet" href="vendor/lib/codemirror/lib/codemirror.css">
<style> <style>
.smalltalk { .smalltalk {

View File

@ -30,9 +30,8 @@
"npmRebuild": false, "npmRebuild": false,
"afterSign": "./tools/notarizeMacApp.js", "afterSign": "./tools/notarizeMacApp.js",
"extraResources": [ "extraResources": [
"build/icons/*", "build/icons/**",
"build/images/*", "build/images/**"
"build/lib/*"
], ],
"afterAllArtifactBuild": "./generateSha512.js", "afterAllArtifactBuild": "./generateSha512.js",
"asar": true, "asar": true,

View File

@ -4,8 +4,8 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<script src="UserWebviewIndex.js"></script> <script src="UserWebviewIndex.js"></script>
<link rel="stylesheet" href="../../style/icons/style.css"> <link rel="stylesheet" href="../../style/icons/style.css">
<link rel="stylesheet" href="../../build/lib/@fortawesome/fontawesome-free/css/all.min.css"> <link rel="stylesheet" href="../../vendor/lib/@fortawesome/fontawesome-free/css/all.min.css">
<link rel="stylesheet" href="../../build/lib/roboto-fontface/css/roboto/roboto-fontface.css"> <link rel="stylesheet" href="../../vendor/lib/roboto-fontface/css/roboto/roboto-fontface.css">
<style> <style>
html { html {
overflow: hidden; overflow: hidden;

View File

@ -1,6 +1,6 @@
(function(globalObject) { (function(globalObject) {
// TODO: Not sure if that will work once packaged in Electron // TODO: Not sure if that will work once packaged in Electron
const sandboxProxy = require('../../build/lib/@joplin/lib/services/plugins/sandboxProxy.js'); const sandboxProxy = require('../../vendor/lib/@joplin/lib/services/plugins/sandboxProxy.js');
const ipcRenderer = require('electron').ipcRenderer; const ipcRenderer = require('electron').ipcRenderer;
const ipcRendererSend = (message, args) => { const ipcRendererSend = (message, args) => {

View File

@ -7,7 +7,7 @@ const nodeModulesDir = resolve(__dirname, '../node_modules');
async function main() { async function main() {
const langSourceDir = resolve(__dirname, '../../../Assets/TinyMCE/langs'); const langSourceDir = resolve(__dirname, '../../../Assets/TinyMCE/langs');
const buildLibDir = resolve(__dirname, '../build/lib'); const buildLibDir = resolve(__dirname, '../vendor/lib');
const dirs = [ const dirs = [
'tinymce', 'tinymce',