Merge pull request #22 from vector-im/bwindels/one-build

Unify legacy and normal build
This commit is contained in:
Bruno Windels 2020-08-18 09:49:23 +00:00 committed by GitHub
commit cfa857c40a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 1570 additions and 22 deletions

View File

@ -41,6 +41,7 @@
"postcss-url": "^8.0.0", "postcss-url": "^8.0.0",
"regenerator-runtime": "^0.13.7", "regenerator-runtime": "^0.13.7",
"rollup": "^1.15.6", "rollup": "^1.15.6",
"rollup-plugin-cleanup": "^3.1.1",
"serve-static": "^1.13.2", "serve-static": "^1.13.2",
"xxhash": "^0.3.0" "xxhash": "^0.3.0"
} }

View File

@ -34,6 +34,7 @@ import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs'; import commonjs from '@rollup/plugin-commonjs';
// multi-entry plugin so we can add polyfill file to main // multi-entry plugin so we can add polyfill file to main
import multi from '@rollup/plugin-multi-entry'; import multi from '@rollup/plugin-multi-entry';
import removeJsComments from 'rollup-plugin-cleanup';
// replace urls of asset names with content hashed version // replace urls of asset names with content hashed version
import postcssUrl from "postcss-url"; import postcssUrl from "postcss-url";
@ -52,13 +53,14 @@ const targetDir = path.join(projectDir, "target/");
const program = new commander.Command(); const program = new commander.Command();
program program
.option("--legacy", "make a build for IE11")
.option("--no-offline", "make a build without a service worker or appcache manifest") .option("--no-offline", "make a build without a service worker or appcache manifest")
program.parse(process.argv); program.parse(process.argv);
const {debug, noOffline, legacy} = program; const {debug, noOffline} = program;
const offline = !noOffline; const offline = !noOffline;
async function build() { async function build() {
// only used for CSS for now, using legacy for all targets for now
const legacy = true;
// get version number // get version number
const version = JSON.parse(await fs.readFile(path.join(projectDir, "package.json"), "utf8")).version; const version = JSON.parse(await fs.readFile(path.join(projectDir, "package.json"), "utf8")).version;
@ -74,9 +76,10 @@ async function build() {
// also creates the directories where the theme css bundles are placed in, // also creates the directories where the theme css bundles are placed in,
// so do it first // so do it first
const themeAssets = await copyThemeAssets(themes, legacy); const themeAssets = await copyThemeAssets(themes, legacy);
const jsBundlePath = await (legacy ? buildJsLegacy() : buildJs()); const jsBundlePath = await buildJs();
const jsLegacyBundlePath = await buildJsLegacy();
const cssBundlePaths = await buildCssBundles(legacy ? buildCssLegacy : buildCss, themes, themeAssets); const cssBundlePaths = await buildCssBundles(legacy ? buildCssLegacy : buildCss, themes, themeAssets);
const assetPaths = createAssetPaths(jsBundlePath, cssBundlePaths, themeAssets); const assetPaths = createAssetPaths(jsBundlePath, jsLegacyBundlePath, cssBundlePaths, themeAssets);
let manifestPath; let manifestPath;
if (offline) { if (offline) {
@ -84,10 +87,10 @@ async function build() {
} }
await buildHtml(doc, version, assetPaths, manifestPath); await buildHtml(doc, version, assetPaths, manifestPath);
console.log(`built ${PROJECT_ID}${legacy ? " legacy" : ""} ${version} successfully`); console.log(`built ${PROJECT_ID} ${version} successfully`);
} }
function createAssetPaths(jsBundlePath, cssBundlePaths, themeAssets) { function createAssetPaths(jsBundlePath, jsLegacyBundlePath, cssBundlePaths, themeAssets) {
function trim(path) { function trim(path) {
if (!path.startsWith(targetDir)) { if (!path.startsWith(targetDir)) {
throw new Error("invalid target path: " + targetDir); throw new Error("invalid target path: " + targetDir);
@ -96,6 +99,7 @@ function createAssetPaths(jsBundlePath, cssBundlePaths, themeAssets) {
} }
return { return {
jsBundle: () => trim(jsBundlePath), jsBundle: () => trim(jsBundlePath),
jsLegacyBundle: () => trim(jsLegacyBundlePath),
cssMainBundle: () => trim(cssBundlePaths.main), cssMainBundle: () => trim(cssBundlePaths.main),
cssThemeBundle: themeName => trim(cssBundlePaths.themes[themeName]), cssThemeBundle: themeName => trim(cssBundlePaths.themes[themeName]),
cssThemeBundles: () => Object.values(cssBundlePaths.themes).map(a => trim(a)), cssThemeBundles: () => Object.values(cssBundlePaths.themes).map(a => trim(a)),
@ -150,8 +154,9 @@ async function buildHtml(doc, version, assetPaths, manifestPath) {
theme.attr("href", assetPaths.cssThemeBundle(themeName)); theme.attr("href", assetPaths.cssThemeBundle(themeName));
}); });
doc("script#main").replaceWith( doc("script#main").replaceWith(
`<script type="text/javascript" src="${assetPaths.jsBundle()}"></script>` + `<script type="module">import {main} from "./${assetPaths.jsBundle()}"; main(document.body);</script>` +
`<script type="text/javascript">${PROJECT_ID}Bundle.main(document.body);</script>`); `<script type="text/javascript" nomodule src="${assetPaths.jsLegacyBundle()}"></script>` +
`<script type="text/javascript" nomodule>${PROJECT_ID}Bundle.main(document.body);</script>`);
removeOrEnableScript(doc("script#service-worker"), offline); removeOrEnableScript(doc("script#service-worker"), offline);
const versionScript = doc("script#version"); const versionScript = doc("script#version");
@ -169,13 +174,16 @@ async function buildHtml(doc, version, assetPaths, manifestPath) {
async function buildJs() { async function buildJs() {
// create js bundle // create js bundle
const bundle = await rollup.rollup({input: 'src/main.js'}); const bundle = await rollup.rollup({
input: 'src/main.js',
plugins: [removeJsComments({comments: "none"})]
});
const {output} = await bundle.generate({ const {output} = await bundle.generate({
format: 'iife', format: 'es',
name: `${PROJECT_ID}Bundle` name: `${PROJECT_ID}Bundle`
}); });
const code = output[0].code; const code = output[0].code;
const bundlePath = resource(`${PROJECT_ID}.js`, code); const bundlePath = resource(`${PROJECT_ID}.mjs`, code);
await fs.writeFile(bundlePath, code, "utf8"); await fs.writeFile(bundlePath, code, "utf8");
return bundlePath; return bundlePath;
} }
@ -199,7 +207,7 @@ async function buildJsLegacy() {
// create js bundle // create js bundle
const rollupConfig = { const rollupConfig = {
input: ['src/legacy-polyfill.js', 'src/main.js'], input: ['src/legacy-polyfill.js', 'src/main.js'],
plugins: [multi(), commonjs(), nodeResolve(), babelPlugin] plugins: [multi(), commonjs(), nodeResolve(), babelPlugin, removeJsComments({comments: "none"})]
}; };
const bundle = await rollup.rollup(rollupConfig); const bundle = await rollup.rollup(rollupConfig);
const {output} = await bundle.generate({ const {output} = await bundle.generate({
@ -215,27 +223,27 @@ async function buildJsLegacy() {
async function buildOffline(version, assetPaths) { async function buildOffline(version, assetPaths) {
// write offline availability // write offline availability
const offlineFiles = [ const offlineFiles = [
assetPaths.jsBundle(),
assetPaths.cssMainBundle(), assetPaths.cssMainBundle(),
"index.html", "index.html",
"icon-192.png", "icon-192.png",
].concat(assetPaths.cssThemeBundles()); ].concat(assetPaths.cssThemeBundles());
// write appcache manifest // write appcache manifest
const manifestLines = [ const appCacheLines = [
`CACHE MANIFEST`, `CACHE MANIFEST`,
`# v${version}`, `# v${version}`,
`NETWORK`, `NETWORK`,
`"*"`, `"*"`,
`CACHE`, `CACHE`,
]; ];
manifestLines.push(...offlineFiles); appCacheLines.push(assetPaths.jsLegacyBundle(), ...offlineFiles);
const manifest = manifestLines.join("\n") + "\n"; const swOfflineFiles = [assetPaths.jsBundle(), ...offlineFiles];
await fs.writeFile(path.join(targetDir, "manifest.appcache"), manifest, "utf8"); const appCacheManifest = appCacheLines.join("\n") + "\n";
await fs.writeFile(path.join(targetDir, "manifest.appcache"), appCacheManifest, "utf8");
// write service worker // write service worker
let swSource = await fs.readFile(path.join(projectDir, "src/service-worker.template.js"), "utf8"); let swSource = await fs.readFile(path.join(projectDir, "src/service-worker.template.js"), "utf8");
swSource = swSource.replace(`"%%VERSION%%"`, `"${version}"`); swSource = swSource.replace(`"%%VERSION%%"`, `"${version}"`);
swSource = swSource.replace(`"%%OFFLINE_FILES%%"`, JSON.stringify(offlineFiles)); swSource = swSource.replace(`"%%OFFLINE_FILES%%"`, JSON.stringify(swOfflineFiles));
swSource = swSource.replace(`"%%CACHE_FILES%%"`, JSON.stringify(assetPaths.otherAssets())); swSource = swSource.replace(`"%%CACHE_FILES%%"`, JSON.stringify(assetPaths.otherAssets()));
await fs.writeFile(path.join(targetDir, "sw.js"), swSource, "utf8"); await fs.writeFile(path.join(targetDir, "sw.js"), swSource, "utf8");
// write web manifest // write web manifest

1547
yarn.lock

File diff suppressed because it is too large Load Diff