forked from mystiq/hydrogen-web
Merge pull request #22 from vector-im/bwindels/one-build
Unify legacy and normal build
This commit is contained in:
commit
cfa857c40a
3 changed files with 1570 additions and 22 deletions
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue