From 919d22414dd21423a9bfa49e31722d89d0f21ab5 Mon Sep 17 00:00:00 2001 From: Kendell R Date: Wed, 11 Oct 2023 00:31:25 +0000 Subject: [PATCH] Switch to Lightning CSS --- build-scripts/bundle.cjs | 136 ++++++++++++++++--------------- build-scripts/gulp/entry-html.js | 3 + build-scripts/lightningcss.cjs | 52 ++++++++++++ package.json | 1 + yarn.lock | 110 +++++++++++++++++++++++++ 5 files changed, 236 insertions(+), 66 deletions(-) create mode 100644 build-scripts/lightningcss.cjs diff --git a/build-scripts/bundle.cjs b/build-scripts/bundle.cjs index b359a0737487..32bf89af473f 100644 --- a/build-scripts/bundle.cjs +++ b/build-scripts/bundle.cjs @@ -1,6 +1,7 @@ const path = require("path"); const env = require("./env.cjs"); const paths = require("./paths.cjs"); +const lightningcss = require("./lightningcss.cjs"); // GitHub base URL to use for production source maps // Nightly builds use the commit SHA, otherwise assumes there is a tag that matches the version @@ -69,9 +70,6 @@ module.exports.htmlMinifierOptions = { decodeEntities: true, removeComments: true, removeRedundantAttributes: true, - minifyCSS: { - compatibility: "*,-properties.zeroUnits", - }, }; module.exports.terserOptions = ({ latestBuild, isTestBuild }) => ({ @@ -82,72 +80,78 @@ module.exports.terserOptions = ({ latestBuild, isTestBuild }) => ({ sourceMap: !isTestBuild, }); -module.exports.babelOptions = ({ latestBuild, isProdBuild, isTestBuild }) => ({ - babelrc: false, - compact: false, - assumptions: { - privateFieldsAsProperties: true, - setPublicClassFields: true, - setSpreadProperties: true, - }, - browserslistEnv: latestBuild ? "modern" : "legacy", - // Must be unambiguous because some dependencies are CommonJS only - sourceType: "unambiguous", - presets: [ - [ - "@babel/preset-env", - { - useBuiltIns: latestBuild ? false : "entry", - corejs: latestBuild ? false : { version: "3.33", proposals: true }, - bugfixes: true, - shippedProposals: true, - }, - ], - "@babel/preset-typescript", - ], - plugins: [ - [ - path.resolve( - paths.polymer_dir, - "build-scripts/babel-plugins/inline-constants-plugin.cjs" - ), - { - modules: ["@mdi/js"], - ignoreModuleNotFound: true, - }, - ], - // Minify template literals for production - isProdBuild && [ - "template-html-minifier", - { - modules: { - lit: [ - "html", - { name: "svg", encapsulation: "svg" }, - { name: "css", encapsulation: "style" }, - ], - "@polymer/polymer/lib/utils/html-tag": ["html"], +module.exports.babelOptions = ({ latestBuild, isProdBuild, isTestBuild }) => { + const minifyCSS = lightningcss.getMinifyCSS({ latestBuild, isProdBuild }); + return { + babelrc: false, + compact: false, + assumptions: { + privateFieldsAsProperties: true, + setPublicClassFields: true, + setSpreadProperties: true, + }, + browserslistEnv: latestBuild ? "modern" : "legacy", + // Must be unambiguous because some dependencies are CommonJS only + sourceType: "unambiguous", + presets: [ + [ + "@babel/preset-env", + { + useBuiltIns: latestBuild ? false : "entry", + corejs: latestBuild ? false : { version: "3.33", proposals: true }, + bugfixes: true, + shippedProposals: true, }, - strictCSS: true, - htmlMinifier: module.exports.htmlMinifierOptions, - failOnError: true, // we can turn this off in case of false positives - }, + ], + "@babel/preset-typescript", ], - // Import helpers and regenerator from runtime package - [ - "@babel/plugin-transform-runtime", - { version: require("../package.json").dependencies["@babel/runtime"] }, + plugins: [ + [ + path.resolve( + paths.polymer_dir, + "build-scripts/babel-plugins/inline-constants-plugin.cjs" + ), + { + modules: ["@mdi/js"], + ignoreModuleNotFound: true, + }, + ], + // Minify template literals for production + [ + "template-html-minifier", + { + modules: { + lit: [ + "html", + { name: "svg", encapsulation: "svg" }, + { name: "css", encapsulation: "style" }, + ], + "@polymer/polymer/lib/utils/html-tag": ["html"], + }, + strictCSS: true, + htmlMinifier: { + ...module.exports.htmlMinifierOptions, + minifyCSS, + }, + failOnError: true, // we can turn this off in case of false positives + }, + ], + // Import helpers and regenerator from runtime package + [ + "@babel/plugin-transform-runtime", + { version: require("../package.json").dependencies["@babel/runtime"] }, + ], + // Support some proposals still in TC39 process + ["@babel/plugin-proposal-decorators", { decoratorsBeforeExport: true }], + ].filter(Boolean), + exclude: [ + // \\ for Windows, / for Mac OS and Linux + /node_modules[\\/]core-js/, + /node_modules[\\/]webpack[\\/]buildin/, ], - // Support some proposals still in TC39 process - ["@babel/plugin-proposal-decorators", { decoratorsBeforeExport: true }], - ].filter(Boolean), - exclude: [ - // \\ for Windows, / for Mac OS and Linux - /node_modules[\\/]core-js/, - /node_modules[\\/]webpack[\\/]buildin/, - ], - sourceMaps: !isTestBuild, -}); + sourceMaps: !isTestBuild, + }; +}; const nameSuffix = (latestBuild) => (latestBuild ? "-latest" : "-es5"); diff --git a/build-scripts/gulp/entry-html.js b/build-scripts/gulp/entry-html.js index dd6285c3103a..f11128174ef7 100644 --- a/build-scripts/gulp/entry-html.js +++ b/build-scripts/gulp/entry-html.js @@ -8,6 +8,7 @@ import path from "path"; import { htmlMinifierOptions, terserOptions } from "../bundle.cjs"; import env from "../env.cjs"; import paths from "../paths.cjs"; +import { getMinifyCSS } from "../lightningcss.cjs"; const renderTemplate = (templateFile, data = {}) => { const compiled = template( @@ -32,9 +33,11 @@ const minifyHtml = (content, ext) => { const wrapTag = WRAP_TAGS[ext] || ""; const begTag = wrapTag && `<${wrapTag}>`; const endTag = wrapTag && ``; + const minifyCSS = getMinifyCSS({ latestBuild: false, isProdBuild: true }); // Transpile and minify return minify(begTag + content + endTag, { ...htmlMinifierOptions, conservativeCollapse: false, + minifyCSS, minifyJS: terserOptions({ latestBuild: false, // Shared scripts should be ES5 isTestBuild: true, // Don't need source maps diff --git a/build-scripts/lightningcss.cjs b/build-scripts/lightningcss.cjs new file mode 100644 index 000000000000..11457db89c0f --- /dev/null +++ b/build-scripts/lightningcss.cjs @@ -0,0 +1,52 @@ +const browserslist = require("browserslist"); +const lightningcss = require("lightningcss"); + +const decoder = new TextDecoder(); +function wrapCSS(text, type) { + switch (type) { + case "inline": + return "section{" + text + "}"; + case "media": + return "@media " + text + "{section{top:0}}"; + default: + return text; + } +} +function unwrapCSS(text, type) { + let matches; + switch (type) { + case "inline": + matches = text.match(/^section\{([\s\S]*)\}$/); + break; + case "media": + matches = text.match(/^@media ([\s\S]*?)\s*{[\s\S]*}$/); + break; + } + return matches ? matches[1] : text; +} + +module.exports.getMinifyCSS = ({ latestBuild, isProdBuild }) => { + const cssTargets = lightningcss.browserslistToTargets( + browserslist( + browserslist.loadConfig({ + path: ".", + env: latestBuild ? "modern" : "legacy", + }), + { throwOnMissing: true, mobileToDesktop: true } + ) + ); + return (text, type) => { + const input = wrapCSS(text, type); + const { code, warnings } = lightningcss.transform({ + filename: "style.css", + code: Buffer.from(input), + minify: isProdBuild, + targets: cssTargets, + }); + if (warnings.length > 0) { + console.warn("Warnings while transforming CSS:", ...warnings); + } + const output = decoder.decode(code); + return unwrapCSS(output, type); + }; +}; diff --git a/package.json b/package.json index 5434f52d3a75..e1b863e8ed31 100644 --- a/package.json +++ b/package.json @@ -220,6 +220,7 @@ "husky": "8.0.3", "instant-mocha": "1.5.2", "jszip": "3.10.1", + "lightningcss": "1.22.0", "lint-staged": "14.0.1", "lit-analyzer": "2.0.0-pre.3", "lodash.template": "4.5.0", diff --git a/yarn.lock b/yarn.lock index 3a4c90ab742b..6e18fd574373 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7506,6 +7506,15 @@ __metadata: languageName: node linkType: hard +"detect-libc@npm:^1.0.3": + version: 1.0.3 + resolution: "detect-libc@npm:1.0.3" + bin: + detect-libc: ./bin/detect-libc.js + checksum: daaaed925ffa7889bd91d56e9624e6c8033911bb60f3a50a74a87500680652969dbaab9526d1e200a4c94acf80fc862a22131841145a0a8482d60a99c24f4a3e + languageName: node + linkType: hard + "detect-node@npm:^2.0.4": version: 2.1.0 resolution: "detect-node@npm:2.1.0" @@ -9788,6 +9797,7 @@ __metadata: jszip: 3.10.1 leaflet: 1.9.4 leaflet-draw: 1.0.4 + lightningcss: 1.22.0 lint-staged: 14.0.1 lit: 2.8.0 lit-analyzer: 2.0.0-pre.3 @@ -11371,6 +11381,106 @@ __metadata: languageName: node linkType: hard +"lightningcss-darwin-arm64@npm:1.22.0": + version: 1.22.0 + resolution: "lightningcss-darwin-arm64@npm:1.22.0" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"lightningcss-darwin-x64@npm:1.22.0": + version: 1.22.0 + resolution: "lightningcss-darwin-x64@npm:1.22.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"lightningcss-freebsd-x64@npm:1.22.0": + version: 1.22.0 + resolution: "lightningcss-freebsd-x64@npm:1.22.0" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"lightningcss-linux-arm-gnueabihf@npm:1.22.0": + version: 1.22.0 + resolution: "lightningcss-linux-arm-gnueabihf@npm:1.22.0" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"lightningcss-linux-arm64-gnu@npm:1.22.0": + version: 1.22.0 + resolution: "lightningcss-linux-arm64-gnu@npm:1.22.0" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"lightningcss-linux-arm64-musl@npm:1.22.0": + version: 1.22.0 + resolution: "lightningcss-linux-arm64-musl@npm:1.22.0" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"lightningcss-linux-x64-gnu@npm:1.22.0": + version: 1.22.0 + resolution: "lightningcss-linux-x64-gnu@npm:1.22.0" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"lightningcss-linux-x64-musl@npm:1.22.0": + version: 1.22.0 + resolution: "lightningcss-linux-x64-musl@npm:1.22.0" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"lightningcss-win32-x64-msvc@npm:1.22.0": + version: 1.22.0 + resolution: "lightningcss-win32-x64-msvc@npm:1.22.0" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"lightningcss@npm:1.22.0": + version: 1.22.0 + resolution: "lightningcss@npm:1.22.0" + dependencies: + detect-libc: ^1.0.3 + lightningcss-darwin-arm64: 1.22.0 + lightningcss-darwin-x64: 1.22.0 + lightningcss-freebsd-x64: 1.22.0 + lightningcss-linux-arm-gnueabihf: 1.22.0 + lightningcss-linux-arm64-gnu: 1.22.0 + lightningcss-linux-arm64-musl: 1.22.0 + lightningcss-linux-x64-gnu: 1.22.0 + lightningcss-linux-x64-musl: 1.22.0 + lightningcss-win32-x64-msvc: 1.22.0 + dependenciesMeta: + lightningcss-darwin-arm64: + optional: true + lightningcss-darwin-x64: + optional: true + lightningcss-freebsd-x64: + optional: true + lightningcss-linux-arm-gnueabihf: + optional: true + lightningcss-linux-arm64-gnu: + optional: true + lightningcss-linux-arm64-musl: + optional: true + lightningcss-linux-x64-gnu: + optional: true + lightningcss-linux-x64-musl: + optional: true + lightningcss-win32-x64-msvc: + optional: true + checksum: 6b9a04846243a2161ac12ee098f9c2143a1a06fb683228ef0433473257751a709b0bafa195efa8d3d8f1556ca60c54f5434caeb172874a8daced552dedcbed93 + languageName: node + linkType: hard + "lilconfig@npm:2.1.0": version: 2.1.0 resolution: "lilconfig@npm:2.1.0"