Skip to content

Commit

Permalink
Use ES modules and dynamic import for Webpack latest builds (home-ass…
Browse files Browse the repository at this point in the history
  • Loading branch information
steverep authored Jun 13, 2023
1 parent 197638b commit fa1a6af
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 22 deletions.
6 changes: 6 additions & 0 deletions .browserslistrc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ supports es6-module-dynamic-import
not Safari < 13
not iOS < 13

# Exclude KaiOS, QQ, and UC browsers due to lack of sufficient feature support data
# Babel ignores these automatically, but we need here for Webpack to output ESM with dynamic imports
not KaiOS > 0
not QQAndroid > 0
not UCAndroid > 0

# Exclude unsupported browsers
not dead

Expand Down
1 change: 1 addition & 0 deletions build-scripts/bundle.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ module.exports.htmlMinifierOptions = {
module.exports.terserOptions = ({ latestBuild, isTestBuild }) => ({
safari10: !latestBuild,
ecma: latestBuild ? 2015 : 5,
module: latestBuild,
format: { comments: false },
sourceMap: !isTestBuild,
});
Expand Down
12 changes: 10 additions & 2 deletions build-scripts/webpack.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const createWebpackConfig = ({
return {
name,
mode: isProdBuild ? "production" : "development",
target: ["web", latestBuild ? "es2017" : "es5"],
target: `browserslist:${latestBuild ? "modern" : "legacy"}`,
// For tests/CI, source maps are skipped to gain build speed
// For production, generate source maps for accurate stack traces without source code
// For development, generate "cheap" versions that can map to original line numbers
Expand Down Expand Up @@ -84,6 +84,13 @@ const createWebpackConfig = ({
],
moduleIds: isProdBuild && !isStatsBuild ? "deterministic" : "named",
chunkIds: isProdBuild && !isStatsBuild ? "deterministic" : "named",
splitChunks: {
// Disable splitting for web workers with ESM output
// Imports of external chunks are broken
chunks: latestBuild
? (chunk) => !chunk.canBeInitial() && !/^.+-worker$/.test(chunk.name)
: undefined,
},
},
plugins: [
!isStatsBuild && new WebpackBar({ fancy: !isProdBuild }),
Expand Down Expand Up @@ -163,6 +170,7 @@ const createWebpackConfig = ({
},
},
output: {
module: latestBuild,
filename: ({ chunk }) =>
!isProdBuild || isStatsBuild || dontHash.has(chunk.name)
? "[name].js"
Expand Down Expand Up @@ -196,7 +204,7 @@ const createWebpackConfig = ({
: undefined,
},
experiments: {
topLevelAwait: true,
outputModule: true,
},
};
};
Expand Down
33 changes: 17 additions & 16 deletions src/components/data-table/sort-filter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Remote, wrap } from "comlink";
import type { Api } from "./sort_filter_worker";
import type { Api } from "./sort-filter-worker";

type FilterDataType = Api["filterData"];
type FilterDataParamTypes = Parameters<FilterDataType>;
Expand All @@ -9,27 +9,28 @@ type SortDataParamTypes = Parameters<SortDataType>;

let worker: Remote<Api> | undefined;

export const filterData = (
data: FilterDataParamTypes[0],
columns: FilterDataParamTypes[1],
filter: FilterDataParamTypes[2]
): Promise<ReturnType<FilterDataType>> => {
const getWorker = () => {
if (!worker) {
worker = wrap(new Worker(new URL("./sort_filter_worker", import.meta.url)));
worker = wrap(
new Worker(
/* webpackChunkName: "sort-filter-worker" */
new URL("./sort-filter-worker", import.meta.url)
)
);
}

return worker.filterData(data, columns, filter);
return worker;
};

export const filterData = (
data: FilterDataParamTypes[0],
columns: FilterDataParamTypes[1],
filter: FilterDataParamTypes[2]
): Promise<ReturnType<FilterDataType>> =>
getWorker().filterData(data, columns, filter);
export const sortData = (
data: SortDataParamTypes[0],
columns: SortDataParamTypes[1],
direction: SortDataParamTypes[2],
sortColumn: SortDataParamTypes[3]
): Promise<ReturnType<SortDataType>> => {
if (!worker) {
worker = wrap(new Worker(new URL("./sort_filter_worker", import.meta.url)));
}

return worker.sortData(data, columns, direction, sortColumn);
};
): Promise<ReturnType<SortDataType>> =>
getWorker().sortData(data, columns, direction, sortColumn);
File renamed without changes.
10 changes: 7 additions & 3 deletions src/resources/render-markdown.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Remote, wrap } from "comlink";
import type { Api } from "./markdown_worker";
import type { Api } from "./markdown-worker";

type RenderMarkdownType = Api["renderMarkdown"];
type RenderMarkdownParamTypes = Parameters<RenderMarkdownType>;
Expand All @@ -12,8 +12,12 @@ export const renderMarkdown = async (
hassOptions?: RenderMarkdownParamTypes[2]
): Promise<ReturnType<RenderMarkdownType>> => {
if (!worker) {
worker = wrap(new Worker(new URL("./markdown_worker", import.meta.url)));
worker = wrap(
new Worker(
/* webpackChunkName: "markdown-worker" */
new URL("./markdown-worker", import.meta.url)
)
);
}

return worker.renderMarkdown(content, markedOptions, hassOptions);
};
7 changes: 6 additions & 1 deletion test/webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import webpack from "../build-scripts/webpack.cjs";

export default webpack.createAppConfig({
const config = webpack.createAppConfig({
isProdBuild: false,
latestBuild: true,
isStatsBuild: false,
isTestBuild: true,
});

// instant-mocha forces a CJS library, so cannot output ESM
config.output.module = false;

export default config;

0 comments on commit fa1a6af

Please sign in to comment.