split lowlight languages out of the worker bundle

This commit is contained in:
Sebastian Sdorra
2020-01-27 13:30:46 +01:00
parent 3eb444a1fe
commit 3a8ae34e89
10 changed files with 1869 additions and 1563 deletions

View File

@@ -20,7 +20,8 @@
}, },
"resolutions": { "resolutions": {
"babel-core": "7.0.0-bridge.0", "babel-core": "7.0.0-bridge.0",
"gitdiff-parser": "https://github.com/scm-manager/gitdiff-parser#ed3fe7de73dbb0a06c3e6adbbdf22dbae6e66351" "gitdiff-parser": "https://github.com/scm-manager/gitdiff-parser#ed3fe7de73dbb0a06c3e6adbbdf22dbae6e66351",
"lowlight": "1.13.1"
}, },
"babel": { "babel": {
"presets": [ "presets": [

View File

@@ -25,8 +25,7 @@ module.exports = {
transformIgnorePatterns: ["node_modules/(?!(@scm-manager)/)"], transformIgnorePatterns: ["node_modules/(?!(@scm-manager)/)"],
moduleNameMapper: { moduleNameMapper: {
"\\.(png|svg|jpg|gif|woff2?|eot|ttf)$": path.join(mockDirectory, "fileMock.js"), "\\.(png|svg|jpg|gif|woff2?|eot|ttf)$": path.join(mockDirectory, "fileMock.js"),
"\\.(css|scss|sass)$": path.join(mockDirectory, "styleMock.js"), "\\.(css|scss|sass)$": path.join(mockDirectory, "styleMock.js")
"\\.worker$": path.join(mockDirectory, "workerMock.js")
}, },
setupFiles: [path.resolve(__dirname, "src", "setup.js")], setupFiles: [path.resolve(__dirname, "src", "setup.js")],
collectCoverage: true, collectCoverage: true,

View File

@@ -1,2 +1,4 @@
import registerRequireContextHook from "babel-plugin-require-context-hook/register"; import registerRequireContextHook from "babel-plugin-require-context-hook/register";
import Worker from "./__mocks__/workerMock";
registerRequireContextHook(); registerRequireContextHook();
window.Worker = Worker;

View File

@@ -1,8 +1,11 @@
/* eslint-disable no-restricted-globals */
// @ts-ignore we have no types for react-diff-view // @ts-ignore we have no types for react-diff-view
import { tokenize } from "react-diff-view"; import { tokenize } from "react-diff-view";
import refractor from "./refractorAdapter"; import refractor from "./refractorAdapter";
// the WorkerGlobalScope is assigned to self
// see https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/self
declare const self: Worker;
self.addEventListener("message", ({ data: { id, payload } }) => { self.addEventListener("message", ({ data: { id, payload } }) => {
const { hunks, language } = payload; const { hunks, language } = payload;
const options = { const options = {
@@ -10,20 +13,27 @@ self.addEventListener("message", ({ data: { id, payload } }) => {
language: language, language: language,
refractor refractor
}; };
try {
const tokens = tokenize(hunks, options); const doTokenization = (worker: Worker) => {
const payload = { try {
success: true, const tokens = tokenize(hunks, options);
tokens: tokens const payload = {
}; success: true,
// @ts-ignore seems to use wrong typing tokens: tokens
self.postMessage({ id, payload }); };
} catch (ex) { worker.postMessage({ id, payload });
const payload = { } catch (ex) {
success: false, const payload = {
reason: ex.message success: false,
}; reason: ex.message
// @ts-ignore seems to use wrong typing };
self.postMessage({ id, payload }); worker.postMessage({ id, payload });
}
};
const createTokenizer = (worker: Worker) => () => doTokenization(worker);
if (options.highlight) {
refractor.loadLanguage(language, createTokenizer(self));
} }
}); });

View File

@@ -2,8 +2,6 @@ import React, { FC } from "react";
import styled from "styled-components"; import styled from "styled-components";
// @ts-ignore we have no typings for react-diff-view // @ts-ignore we have no typings for react-diff-view
import { Diff, useTokenizeWorker } from "react-diff-view"; import { Diff, useTokenizeWorker } from "react-diff-view";
// @ts-ignore we use webpack worker-loader to load the web worker
import TokenizeWorker from "./Tokenize.worker";
import { File } from "./DiffTypes"; import { File } from "./DiffTypes";
// styling for the diff tokens // styling for the diff tokens
@@ -38,7 +36,7 @@ const DiffView = styled(Diff)`
`; `;
// WebWorker which creates tokens for syntax highlighting // WebWorker which creates tokens for syntax highlighting
const tokenize = new TokenizeWorker(); const tokenize = new Worker("./Tokenize.worker.ts", { name: "tokenizer", type: "module" });
type Props = { type Props = {
file: File; file: File;

View File

@@ -1,11 +1,33 @@
import lowlight from "lowlight"; import lowlight from "lowlight/lib/core";
// adapter to let lowlight look like refractor // adapter to let lowlight look like refractor
// this is required because react-diff-view does only support refractor, // this is required because react-diff-view does only support refractor,
// but we want same highlighting as in the source code browser. // but we want same highlighting as in the source code browser.
const isLanguageRegistered = (lang: string) => {
// @ts-ignore listLanguages seems unknown to type
const registeredLanguages = lowlight.listLanguages();
return !!registeredLanguages[lang];
};
const loadLanguage = (lang: string, callback: () => void) => {
if (isLanguageRegistered(lang)) {
callback();
} else {
import(
/* webpackChunkName: "tokenizer-lowlight-[request]" */
`highlight.js/lib/languages/${lang}`
).then(loadedLanguage => {
lowlight.registerLanguage(lang, loadedLanguage.default);
callback();
});
}
};
const refractorAdapter = { const refractorAdapter = {
...lowlight, ...lowlight,
isLanguageRegistered,
loadLanguage,
highlight: (value: string, language: string) => { highlight: (value: string, language: string) => {
return lowlight.highlight(language, value).value; return lowlight.highlight(language, value).value;
} }

View File

@@ -9,7 +9,6 @@ const createNodeMock = (element: any) => {
querySelector: (selector: string) => {} querySelector: (selector: string) => {}
}; };
} }
return null;
}; };
initStoryshots({ initStoryshots({
@@ -17,6 +16,7 @@ initStoryshots({
// fix snapshot tests with react-diff-view which uses a ref on tr // fix snapshot tests with react-diff-view which uses a ref on tr
// @see https://github.com/storybookjs/storybook/pull/1090 // @see https://github.com/storybookjs/storybook/pull/1090
test: snapshotWithOptions({ test: snapshotWithOptions({
// @ts-ignore types seems not to match
createNodeMock createNodeMock
}) })
}); });

View File

@@ -12,7 +12,6 @@
"dependencies": { "dependencies": {
"@pmmmwh/react-refresh-webpack-plugin": "^0.1.3", "@pmmmwh/react-refresh-webpack-plugin": "^0.1.3",
"babel-loader": "^8.0.6", "babel-loader": "^8.0.6",
"cache-loader": "^4.1.0",
"css-loader": "^3.2.0", "css-loader": "^3.2.0",
"file-loader": "^4.2.0", "file-loader": "^4.2.0",
"mini-css-extract-plugin": "^0.8.0", "mini-css-extract-plugin": "^0.8.0",
@@ -23,11 +22,10 @@
"sass-loader": "^8.0.0", "sass-loader": "^8.0.0",
"script-loader": "^0.7.2", "script-loader": "^0.7.2",
"style-loader": "^1.0.0", "style-loader": "^1.0.0",
"thread-loader": "^2.1.3",
"worker-loader": "^2.0.0",
"webpack": "^4.41.5", "webpack": "^4.41.5",
"webpack-cli": "^3.3.10", "webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.10.1" "webpack-dev-server": "^3.10.1",
"worker-plugin": "^3.2.0"
}, },
"eslintConfig": { "eslintConfig": {
"extends": "@scm-manager/eslint-config", "extends": "@scm-manager/eslint-config",
@@ -37,5 +35,6 @@
}, },
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"
} },
"devDependencies": {}
} }

View File

@@ -3,14 +3,28 @@ const createIndexMiddleware = require("./middleware/IndexMiddleware");
const createContextPathMiddleware = require("./middleware/ContextPathMiddleware"); const createContextPathMiddleware = require("./middleware/ContextPathMiddleware");
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin"); const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin"); const WorkerPlugin = require("worker-plugin");
const isDevelopment = process.env.NODE_ENV === "development"; const isDevelopment = process.env.NODE_ENV === "development";
const root = path.resolve(process.cwd(), "scm-ui"); const root = path.resolve(process.cwd(), "scm-ui");
const babelPlugins = [];
const webpackPlugins = [new WorkerPlugin()];
let mode = "production";
if (isDevelopment) {
mode = "development";
babelPlugins.push(require.resolve("react-refresh/babel"));
const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin");
webpackPlugins.push(new ReactRefreshWebpackPlugin());
}
console.log(`build ${mode} bundles`);
module.exports = [ module.exports = [
{ {
mode: isDevelopment ? "development" : "production", mode,
context: root, context: root,
entry: { entry: {
webapp: [path.resolve(__dirname, "webpack-public-path.js"), "./ui-webapp/src/index.tsx"] webapp: [path.resolve(__dirname, "webpack-public-path.js"), "./ui-webapp/src/index.tsx"]
@@ -30,26 +44,16 @@ module.exports = [
systemjs: false systemjs: false
} }
}, },
{
test: /\.worker\.(j|t)s$/,
use: { loader: "worker-loader" }
},
{ {
test: /\.(js|ts|jsx|tsx)$/i, test: /\.(js|ts|jsx|tsx)$/i,
exclude: /node_modules/, exclude: /node_modules/,
use: [ use: [
{
loader: "cache-loader"
},
{
loader: "thread-loader"
},
{ {
loader: "babel-loader", loader: "babel-loader",
options: { options: {
cacheDirectory: true, cacheDirectory: true,
presets: ["@scm-manager/babel-preset"], presets: ["@scm-manager/babel-preset"],
plugins: [isDevelopment && require.resolve("react-refresh/babel")].filter(Boolean) plugins: babelPlugins
} }
} }
] ]
@@ -76,7 +80,8 @@ module.exports = [
}, },
output: { output: {
path: path.join(root, "target", "assets"), path: path.join(root, "target", "assets"),
filename: "[name].bundle.js" filename: "[name].bundle.js",
chunkFilename: "[name].bundle.js"
}, },
devServer: { devServer: {
contentBase: path.join(root, "ui-webapp", "public"), contentBase: path.join(root, "ui-webapp", "public"),
@@ -98,6 +103,7 @@ module.exports = [
}, },
optimization: { optimization: {
runtimeChunk: "single", runtimeChunk: "single",
namedChunks: true,
splitChunks: { splitChunks: {
chunks: "all", chunks: "all",
cacheGroups: { cacheGroups: {
@@ -114,7 +120,7 @@ module.exports = [
} }
} }
}, },
plugins: [isDevelopment && new ReactRefreshWebpackPlugin()].filter(Boolean) plugins: webpackPlugins
}, },
{ {
context: root, context: root,

3307
yarn.lock

File diff suppressed because it is too large Load Diff