Browse Source

make zips

tophf 1 year ago
parent
commit
5b551e3ecb
7 changed files with 93 additions and 117 deletions
  1. 6 5
      .gitignore
  2. 1 1
      package.json
  3. 2 2
      src/js/browser.js
  4. 72 0
      tools/build-zip.js
  5. 0 99
      tools/build.js
  6. 1 1
      tools/util.js
  7. 11 9
      webpack.config.js

+ 6 - 5
.gitignore

@@ -1,9 +1,10 @@
 *.zip
 *.tmp*
 .DS_Store
-.eslintcache
-.vscode
 desktop.ini
-dist/
-node_modules/
-yarn.lock
+/.eslintcache
+/.vscode
+/.*.html
+/dist*/
+/node_modules/
+/yarn.lock

+ 1 - 1
package.json

@@ -61,7 +61,7 @@
     "build": "webpack-cli",
     "watch": "webpack-cli watch --node-env DEV",
     "build-icons": "node tools/build-icons",
-    "zip": "npm test && npm build",
+    "zip": "npm test && node tools/build-zip.js",
     "postinstall": "node tools/postinstall.js",
     "preversion": "npm test",
     "version": "sync-version manifest.json && git add .",

+ 2 - 2
src/js/browser.js

@@ -1,7 +1,7 @@
 let browser;
-if (process.env.BUILD === 'CHROME_MV3') {
+if (process.env.NODE_ENV === 'chrome:mv3') {
   browser = self.browser = chrome;
-} else if (process.env.BUILD !== 'FIREFOX' && !window.browser?.runtime) {
+} else if (!(browser = window.browser) || !browser.runtime) {
   /* Auto-promisifier with a fallback to direct call on signature error.
      The fallback isn't used now since we call all synchronous methods via `chrome` */
   const directEvents = ['addListener', 'removeListener', 'hasListener', 'hasListeners'];

+ 72 - 0
tools/build-zip.js

@@ -0,0 +1,72 @@
+#!/usr/bin/env node
+'use strict';
+
+const fs = require('fs');
+const fse = require('fs-extra');
+const glob = require('fast-glob');
+const JSZip = require('jszip');
+const chalk = require('chalk');
+const webpack = require('webpack');
+const {ROOT} = require('./util');
+
+const DST = ROOT + 'dist/';
+const CONFIG_PATH = require.resolve(ROOT + 'webpack.config.js');
+const MANIFEST = 'manifest.json';
+const sChrome = 'chrome';
+const sChromeBeta = 'chrome-beta';
+const sFirefox = 'firefox';
+
+(async function build([targets] = process.argv.slice(2)) {
+  // https://github.com/Stuk/jszip/issues/369
+  const tzBug = new Date().getTimezoneOffset() * 60000;
+  JSZip.defaults.date = new Date(Date.now() - tzBug);
+  for (const target of targets ? targets.split(',') : [sFirefox, sChrome, sChromeBeta]) {
+    process.env.NODE_ENV = target;
+    console.log(chalk.bold(`Building for ${target}...`));
+    fse.emptyDirSync(DST);
+    delete require.cache[CONFIG_PATH];
+    const err = await new Promise(cb => webpack(require(CONFIG_PATH), cb));
+    if (err) throw err;
+    const mj = patchManifest(fs.readFileSync(DST + MANIFEST, 'utf8'), target);
+    const zipName = `stylus-${target}-${mj.version}.zip`;
+    const zip = new JSZip();
+    process.stdout.write(chalk.bold(`Creating ${zipName}...`));
+    for (const e of glob.sync(DST + '**', {
+      ignore: [MANIFEST, '.*.html'],
+      stats: true,
+      onlyFiles: true,
+    })) {
+      zip.file(e.path.slice(DST.length),
+        fs.readFileSync(e.path),
+        {date: new Date(e.stats.mtime - tzBug)});
+    }
+    zip.file(MANIFEST, JSON.stringify(mj, null, 2));
+    fs.writeFileSync(ROOT + zipName,
+      await zip.generateAsync({type: 'nodebuffer', compression: 'DEFLATE'}));
+    console.log(chalk.green(' OK'));
+  }
+})().catch(err => {
+  console.error(err);
+  process.exit(1);
+});
+
+function patchManifest(str, suffix) {
+  const mj = JSON.parse(str);
+  delete mj.key;
+  if (suffix === sChrome) {
+    delete mj.browser_specific_settings;
+  } else if (suffix === sChromeBeta) {
+    delete mj.browser_specific_settings;
+    mj.name = 'Stylus (beta)';
+  } else if (suffix === sFirefox) {
+    mj.options_ui = {
+      /*
+       * Linking to dashboard, not to options, because this is aimed at users who removed the icon
+       * from the toolbar (they rarely use Stylus) so they visit about:addons instead.
+       */
+      page: 'manage.html',
+      open_in_tab: true,
+    };
+  }
+  return mj;
+}

+ 0 - 99
tools/build.js

@@ -1,99 +0,0 @@
-#!/usr/bin/env node
-'use strict';
-
-const fs = require('fs');
-const fse = require('fs-extra');
-const glob = require('fast-glob');
-const JSZip = require('jszip');
-const chalk = require('chalk');
-const {SKIP, transpileCss} = require('./util');
-
-const DST = 'dist';
-const ADD = [
-  '*/**',
-  '*.html',
-  'LICENSE',
-  'README.md',
-  'privacy-policy.md',
-];
-const MANIFEST = 'manifest.json';
-const sChrome = 'chrome';
-const sChromeBeta = 'chrome-beta';
-const sFirefox = 'firefox';
-
-(async function build([target] = process.argv.slice(2)) {
-  const tty = process.stdout.write.bind(process.stdout);
-  const jobTitle = target ? `building as "${target}"` : 'building';
-  tty(jobTitle);
-  const mjStr = fs.readFileSync(MANIFEST, 'utf8');
-  const cssFiles = [];
-  // https://github.com/Stuk/jszip/issues/369
-  const tzBug = target ? 0 : new Date().getTimezoneOffset() * 60000;
-  let zip, addFile;
-  if (!target) {
-    zip = new JSZip();
-    JSZip.defaults.date = new Date(Date.now() - tzBug);
-    addFile = (path, body = fs.readFileSync(path), opts) => zip.file(path, body, opts);
-  } else {
-    fse.emptydirSync(DST);
-    addFile = (path, text) => text
-      ? fse.outputFileSync(DST + '/' + path, text, 'utf8')
-      : fse.copySync(path, DST + '/' + path, {preserveTimestamps: true});
-  }
-  SKIP.push(MANIFEST);
-  for (const e of glob.sync(ADD, {ignore: SKIP, stats: true, onlyFiles: true})) {
-    const date = new Date(e.stats.mtime - tzBug);
-    if (e.path.endsWith('.css') && !e.path.startsWith('vendor')) {
-      cssFiles.push([e.path, fs.readFileSync(e.path, 'utf8'), {date}]);
-    } else {
-      addFile(e.path, undefined, {date});
-    }
-  }
-  let buf;
-  for (const suffix of target ? [target] : [sFirefox, sChrome, sChromeBeta]) {
-    const mj = patchManifest(mjStr, suffix);
-    const zipName = zip && `stylus-${suffix}-${mj.version}.zip`;
-    if (zip) tty(`\r${jobTitle} ${zipName}`);
-    if (buf) zip = await zip.loadAsync(buf); // reusing the already compressed data
-    if (target || suffix !== sChromeBeta) { // reusing sChrome in sChromeBeta
-      tty(', transpiling CSS');
-      for await (const args of transpileCss(cssFiles, suffix === sFirefox, mj)) {
-        addFile(...args);
-        tty('.');
-      }
-    } else {
-      tty('...');
-    }
-    addFile(MANIFEST, JSON.stringify(mj, null, 2));
-    if (zip) {
-      buf = await zip.generateAsync({type: 'nodebuffer', compression: 'DEFLATE'});
-      fs.writeFileSync(zipName, buf);
-    }
-    console.log(chalk.green(' OK'));
-  }
-})().catch(err => {
-  console.error(err);
-  process.exit(1);
-});
-
-function patchManifest(str, suffix) {
-  const mj = JSON.parse(str);
-  delete mj.key;
-  if (suffix === sChrome) {
-    delete mj.browser_specific_settings;
-  } else if (suffix === sChromeBeta) {
-    delete mj.browser_specific_settings;
-    mj.name = 'Stylus (beta)';
-  } else if (suffix === sFirefox) {
-    mj.background.scripts = mj.background.scripts.filter(s => s !== 'js/browser.js');
-    mj.options_ui = {
-      /*
-       * Linking to dashboard, not to options, because this is aimed at users who removed the icon
-       * from the toolbar (they rarely use Stylus) so they visit about:addons instead.
-       */
-      page: 'manage.html',
-      open_in_tab: true,
-    };
-  }
-  return mj;
-}

+ 1 - 1
tools/util.js

@@ -40,7 +40,7 @@ function getBrowserlist() {
   return [
     'Firefox >= ' + mj.browser_specific_settings.gecko.strict_min_version,
     'Chrome >= ' + mj.minimum_chrome_version,
-  ].join(',');
+  ];
 }
 
 function stripSourceMap(buf, from) {

+ 11 - 9
webpack.config.js

@@ -9,18 +9,18 @@ const TerserPlugin = require('terser-webpack-plugin');
 const CopyPlugin = require('copy-webpack-plugin');
 const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
 const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer');
-const {anyPathSep, defineVars, stripSourceMap} = require('./tools/util');
+const {anyPathSep, defineVars, stripSourceMap, ROOT} = require('./tools/util');
 const WebpackPatchBootstrapPlugin = require('./tools/webpack-patch-bootstrap');
 
-const BUILD = process.env.NODE_ENV;
+const [BUILD/*, FLAVOR*/] = process.env.NODE_ENV?.split(':') || [];
 const DEV = BUILD === 'DEV';
 const FS_CACHE = true;
 const REPORT = !true;
-const SRC = `${__dirname}/src/`;
-const DST = path.resolve('dist') + '/';
+const SRC = ROOT + 'src/';
+const DST = ROOT + 'dist/';
 const ASSETS = 'assets/';
 const JS = 'js/';
-const SHIM = path.resolve('tools/shim') + '/';
+const SHIM = ROOT + 'tools/shim/';
 const PAGE_BG = 'background';
 const PAGES = [
   'edit',
@@ -33,7 +33,7 @@ const PAGES = [
 const LIB_EXPORT_DEFAULT = {output: {library: {export: 'default'}}};
 
 const ASSETS_CM = ASSETS + 'cm-themes/';
-const THEME_PATH = 'node_modules/codemirror/theme';
+const THEME_PATH = ROOT + 'node_modules/codemirror/theme';
 const THEME_NAMES = Object.fromEntries(fs.readdirSync(THEME_PATH)
   .sort()
   .map(f => (f = f.match(/([^/\\.]+)\.css$/i)?.[1]) && [f, ''])
@@ -73,6 +73,7 @@ const CFG = {
       }, {
         loader: 'babel-loader',
         test: /\.m?js$/,
+        options: {root: ROOT},
         resolve: {fullySpecified: false},
       }, {
         loader: SHIM + 'null-loader.js',
@@ -141,8 +142,8 @@ const CFG = {
     defineVars({
       ASSETS,
       ASSETS_CM,
+      DEV,
       JS,
-      BUILD,
       PAGE_BG,
     }),
     new WebpackPatchBootstrapPlugin(),
@@ -165,7 +166,7 @@ function mergeCfg(ovr, base) {
     if (FS_CACHE) {
       ovr.cache = {
         ...ovr.cache,
-        name: BUILD + '-' + entry.join('-'),
+        name: (DEV ? 'dev' : 'prod') + '-' + entry.join('-'),
       };
     }
     if (REPORT) {
@@ -298,7 +299,8 @@ module.exports = [
           })),
         ],
       }),
-    ],
+      !DEV && new webpack.ProgressPlugin(),
+    ].filter(Boolean),
     resolve: {
       modules: [
         SHIM,