mirror of
https://github.com/symfony/ux.git
synced 2026-03-24 00:02:21 +01:00
Update tsdown & use @tsdown/css
This update simplifies the tsdown configuration, we do not need our custom plugin to minify CSS anymore (replaced by `css.minify = true`), and same for our hooks that rename the built CSS (replaced by `css.fileName`) 😍
This commit is contained in:
@@ -52,27 +52,19 @@ async function main() {
|
||||
// We force "dependencies" and "peerDependencies" to be external to avoid bundling them.
|
||||
...Object.keys(packageData.dependencies || {}),
|
||||
...Object.keys(packageData.peerDependencies || {}),
|
||||
// The "controllers.js" is generated on-the-fly by StimulusLoaderJavaScriptCompiler
|
||||
...(isStimulusBundle ? ['./controllers.js'] : []),
|
||||
// The "components.js" files are generated on-the-fly by *ControllerLoaderAssetCompiler
|
||||
...(isReactOrVueOrSvelte ? ['./components.js'] : []),
|
||||
]);
|
||||
|
||||
inputFiles.forEach((file) => {
|
||||
// custom handling for StimulusBundle
|
||||
if (file.includes('StimulusBundle/assets/src/loader.ts')) {
|
||||
external.add('./controllers.js');
|
||||
}
|
||||
|
||||
// React, Vue, Svelte
|
||||
if (file.includes('assets/src/loader.ts')) {
|
||||
external.add('./components.js');
|
||||
}
|
||||
});
|
||||
|
||||
const outDir = path.join(packageRoot, 'dist');
|
||||
|
||||
await build({
|
||||
entry: inputFiles,
|
||||
outDir,
|
||||
clean: true,
|
||||
external: Array.from(external),
|
||||
watch: isWatch,
|
||||
format: 'esm',
|
||||
platform: 'browser',
|
||||
target: tsConfigPackage.compilerOptions.target,
|
||||
@@ -80,10 +72,23 @@ async function main() {
|
||||
dts: {
|
||||
entry: inputFiles.filter((inputFile) => !inputFile.endsWith('.css')),
|
||||
},
|
||||
watch: isWatch,
|
||||
...(inputCssFile
|
||||
? {
|
||||
css: {
|
||||
minify: true,
|
||||
fileName: inputCssFile
|
||||
.split('/')
|
||||
.pop()
|
||||
.replace(/\.css$/, '.min.css'),
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
// Prevent esbuild to inline relative and "external" imports (like "./components.js" for React, Vue, Svelte).
|
||||
unbundle: isStimulusBundle || isReactOrVueOrSvelte,
|
||||
inlineOnly: ['idiomorph'],
|
||||
deps: {
|
||||
neverBundle: Array.from(external),
|
||||
onlyBundle: ['idiomorph'],
|
||||
},
|
||||
plugins: [
|
||||
{
|
||||
name: 'symfony-ux:clean-output',
|
||||
@@ -101,62 +106,7 @@ async function main() {
|
||||
return result;
|
||||
},
|
||||
},
|
||||
{
|
||||
/**
|
||||
* Rolldown plugin to minify CSS files using LightningCSS.
|
||||
*
|
||||
* tsdown's `minify: true` only minifies JS, not CSS assets.
|
||||
* We use LightningCSS to minify CSS files.
|
||||
*/
|
||||
name: 'symfony-ux:css-minify',
|
||||
async generateBundle(_options, bundle) {
|
||||
const { transform } = await import('lightningcss');
|
||||
|
||||
for (const [fileName, asset] of Object.entries(bundle)) {
|
||||
if (asset.type !== 'asset' || !fileName.endsWith('.css')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const result = transform({
|
||||
filename: fileName,
|
||||
code: Buffer.from(asset.source as string),
|
||||
minify: true,
|
||||
});
|
||||
|
||||
asset.source = result.code.toString();
|
||||
console.log(`[Symfony UX] Minified CSS: ${fileName}`);
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
hooks: {
|
||||
/**
|
||||
* After the build is complete, rename CSS files to .min.css and remove empty JS wrappers.
|
||||
*/
|
||||
'build:done': async () => {
|
||||
const files = await fs.promises.readdir(outDir);
|
||||
|
||||
for (const file of files) {
|
||||
const filePath = path.join(outDir, file);
|
||||
|
||||
// Rename .css to .min.css
|
||||
if (file.endsWith('.css') && !file.endsWith('.min.css')) {
|
||||
const newPath = filePath.replace(/\.css$/, '.min.css');
|
||||
await fs.promises.rename(filePath, newPath);
|
||||
console.log(`[Symfony UX] Renamed: ${file} → ${path.basename(newPath)}`);
|
||||
|
||||
try {
|
||||
const jsWrapperPath = filePath.replace(/\.css$/, '.js');
|
||||
await fs.promises.access(jsWrapperPath);
|
||||
await fs.promises.unlink(jsWrapperPath);
|
||||
console.log(`[Symfony UX] Removed JS wrapper: ${path.basename(jsWrapperPath)}`);
|
||||
} catch (err) {
|
||||
// No JS wrapper found, nothing to remove
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -21,13 +21,13 @@
|
||||
"@puppeteer/browsers": "^2.13.0",
|
||||
"@testing-library/dom": "^10.4.1",
|
||||
"@testing-library/jest-dom": "^6.9.1",
|
||||
"@tsdown/css": "^0.21.4",
|
||||
"@types/node": "^22.19.11",
|
||||
"lightningcss": "^1.31.1",
|
||||
"oxfmt": "^0.41.0",
|
||||
"oxlint": "^1.56.0",
|
||||
"pkg-types": "^2.3.0",
|
||||
"tinyglobby": "^0.2.15",
|
||||
"tsdown": "^0.20.3",
|
||||
"tsdown": "^0.21.4",
|
||||
"vitest": "^4.1.0"
|
||||
}
|
||||
}
|
||||
|
||||
684
pnpm-lock.yaml
generated
684
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
2
src/Autocomplete/assets/dist/controller.js
vendored
2
src/Autocomplete/assets/dist/controller.js
vendored
@@ -335,4 +335,4 @@ _Class.values = {
|
||||
tomSelectOptions: Object,
|
||||
preload: String
|
||||
};
|
||||
export { _Class as default };
|
||||
export { _Class as default };
|
||||
|
||||
2
src/Chartjs/assets/dist/controller.js
vendored
2
src/Chartjs/assets/dist/controller.js
vendored
@@ -60,4 +60,4 @@ var _Class = class extends Controller {
|
||||
}
|
||||
};
|
||||
_Class.values = { view: Object };
|
||||
export { _Class as default };
|
||||
export { _Class as default };
|
||||
|
||||
2
src/Cropperjs/assets/dist/controller.js
vendored
2
src/Cropperjs/assets/dist/controller.js
vendored
@@ -34,4 +34,4 @@ CropperController.values = {
|
||||
publicUrl: String,
|
||||
options: Object
|
||||
};
|
||||
export { CropperController as default };
|
||||
export { CropperController as default };
|
||||
|
||||
2
src/Cropperjs/assets/dist/style.min.css
vendored
2
src/Cropperjs/assets/dist/style.min.css
vendored
@@ -1 +1 @@
|
||||
.cropperjs-image{max-width:100%}
|
||||
.cropperjs-image{max-width:100%}
|
||||
|
||||
2
src/Dropzone/assets/dist/controller.js
vendored
2
src/Dropzone/assets/dist/controller.js
vendored
@@ -78,4 +78,4 @@ _Class.targets = [
|
||||
"previewFilename",
|
||||
"previewImage"
|
||||
];
|
||||
export { _Class as default };
|
||||
export { _Class as default };
|
||||
|
||||
2
src/Dropzone/assets/dist/style.min.css
vendored
2
src/Dropzone/assets/dist/style.min.css
vendored
@@ -1 +1 @@
|
||||
.dropzone-container{border:2px dashed #bbb;align-items:center;min-height:100px;padding:20px 10px;display:flex;position:relative}.dropzone-input{opacity:0;cursor:pointer;z-index:1;width:100%;height:100%;display:block;position:absolute;top:0;left:0}.dropzone-preview{align-items:center;max-width:100%;display:flex}.dropzone-preview-image{background-position:50%;background-repeat:no-repeat;background-size:contain;flex-basis:0;min-width:50px;max-width:50px;height:50px;margin-right:10px}.dropzone-preview-filename{word-wrap:anywhere}.dropzone-preview-button{z-index:1;width:auto;color:inherit;font:inherit;-webkit-font-smoothing:inherit;-moz-osx-font-smoothing:inherit;-webkit-appearance:none;background:0 0;border:none;margin:0;padding:0;line-height:normal;position:absolute;top:0;right:0;overflow:visible}.dropzone-preview-button:before{content:"×";cursor:pointer;padding:3px 7px}.dropzone-placeholder{text-align:center;color:#999;flex-grow:1}
|
||||
.dropzone-container{border:2px dashed #bbb;align-items:center;min-height:100px;padding:20px 10px;display:flex;position:relative}.dropzone-input{opacity:0;cursor:pointer;z-index:1;width:100%;height:100%;display:block;position:absolute;top:0;left:0}.dropzone-preview{align-items:center;max-width:100%;display:flex}.dropzone-preview-image{background-position:50%;background-repeat:no-repeat;background-size:contain;flex-basis:0;min-width:50px;max-width:50px;height:50px;margin-right:10px}.dropzone-preview-filename{word-wrap:anywhere}.dropzone-preview-button{z-index:1;width:auto;color:inherit;font:inherit;-webkit-font-smoothing:inherit;-moz-osx-font-smoothing:inherit;-webkit-appearance:none;background:0 0;border:none;margin:0;padding:0;line-height:normal;position:absolute;top:0;right:0;overflow:visible}.dropzone-preview-button:before{content:"×";cursor:pointer;padding:3px 7px}.dropzone-placeholder{text-align:center;color:#999;flex-grow:1}
|
||||
|
||||
2
src/LazyImage/assets/dist/controller.js
vendored
2
src/LazyImage/assets/dist/controller.js
vendored
@@ -30,4 +30,4 @@ _Class.values = {
|
||||
src: String,
|
||||
srcset: Object
|
||||
};
|
||||
export { _Class as default };
|
||||
export { _Class as default };
|
||||
|
||||
2
src/LiveComponent/assets/dist/live.min.css
vendored
2
src/LiveComponent/assets/dist/live.min.css
vendored
@@ -1 +1 @@
|
||||
[data-loading=""],[data-loading=show],[data-loading*=\|show]{display:none}
|
||||
[data-loading=""],[data-loading=show],[data-loading*=\|show]{display:none}
|
||||
|
||||
@@ -2337,4 +2337,4 @@ LiveControllerDefault.values = {
|
||||
}
|
||||
};
|
||||
LiveControllerDefault.backendFactory = (controller) => new Backend_default(controller.urlValue, controller.requestMethodValue, controller.fetchCredentialsValue);
|
||||
export { Component, LiveControllerDefault as default, getComponent };
|
||||
export { Component, LiveControllerDefault as default, getComponent };
|
||||
|
||||
@@ -142,4 +142,4 @@ _Class.values = {
|
||||
options: Object,
|
||||
extra: Object
|
||||
};
|
||||
export { IconTypes, _Class as default };
|
||||
export { IconTypes, _Class as default };
|
||||
|
||||
@@ -400,4 +400,4 @@ var map_controller_default = class extends _Class {
|
||||
});
|
||||
}
|
||||
};
|
||||
export { map_controller_default as default };
|
||||
export { map_controller_default as default };
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Controller } from "@hotwired/stimulus";
|
||||
import "leaflet/dist/leaflet.min.css";
|
||||
import * as L from "leaflet";
|
||||
import { CircleOptions, ControlPosition, MapOptions, MarkerOptions, PolylineOptions, PopupOptions } from "leaflet";
|
||||
type Point = {
|
||||
|
||||
@@ -350,4 +350,4 @@ var map_controller_default = class extends _Class {
|
||||
});
|
||||
}
|
||||
};
|
||||
export { map_controller_default as default };
|
||||
export { map_controller_default as default };
|
||||
|
||||
2
src/Notify/assets/dist/controller.js
vendored
2
src/Notify/assets/dist/controller.js
vendored
@@ -60,4 +60,4 @@ _Class.values = {
|
||||
hub: String,
|
||||
topics: Array
|
||||
};
|
||||
export { _Class as default };
|
||||
export { _Class as default };
|
||||
|
||||
2
src/React/assets/dist/components.js
vendored
2
src/React/assets/dist/components.js
vendored
@@ -1,2 +1,2 @@
|
||||
const components = {};
|
||||
export { components };
|
||||
export { components };
|
||||
|
||||
2
src/React/assets/dist/loader.d.ts
vendored
2
src/React/assets/dist/loader.d.ts
vendored
@@ -1,5 +1,5 @@
|
||||
import { ComponentCollection } from "./components.js";
|
||||
import { ComponentClass, FunctionComponent } from "react";
|
||||
import { ComponentCollection } from "./components.js";
|
||||
type Component = string | FunctionComponent<object> | ComponentClass<object, any>;
|
||||
declare global {
|
||||
function resolveReactComponent(name: string): Component;
|
||||
|
||||
2
src/React/assets/dist/loader.js
vendored
2
src/React/assets/dist/loader.js
vendored
@@ -9,4 +9,4 @@ function registerReactControllerComponents(reactComponents = components) {
|
||||
return component;
|
||||
};
|
||||
}
|
||||
export { registerReactControllerComponents };
|
||||
export { registerReactControllerComponents };
|
||||
|
||||
2
src/React/assets/dist/register_controller.js
vendored
2
src/React/assets/dist/register_controller.js
vendored
@@ -17,4 +17,4 @@ function registerReactControllerComponents(context) {
|
||||
return component;
|
||||
};
|
||||
}
|
||||
export { registerReactControllerComponents };
|
||||
export { registerReactControllerComponents };
|
||||
|
||||
2
src/React/assets/dist/render_controller.js
vendored
2
src/React/assets/dist/render_controller.js
vendored
@@ -45,4 +45,4 @@ _Class.values = {
|
||||
default: false
|
||||
}
|
||||
};
|
||||
export { _Class as default };
|
||||
export { _Class as default };
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const eagerControllers = {};
|
||||
const lazyControllers = {};
|
||||
const isApplicationDebug = false;
|
||||
export { eagerControllers, isApplicationDebug, lazyControllers };
|
||||
export { eagerControllers, isApplicationDebug, lazyControllers };
|
||||
|
||||
2
src/StimulusBundle/assets/dist/loader.d.ts
vendored
2
src/StimulusBundle/assets/dist/loader.d.ts
vendored
@@ -1,5 +1,5 @@
|
||||
import { EagerControllersCollection, LazyControllersCollection } from "./controllers.js";
|
||||
import { Application } from "@hotwired/stimulus";
|
||||
import { EagerControllersCollection, LazyControllersCollection } from "./controllers.js";
|
||||
declare const loadControllers: (application: Application, eagerControllers: EagerControllersCollection, lazyControllers: LazyControllersCollection) => void;
|
||||
declare const startStimulusApp: () => Application;
|
||||
export { loadControllers, startStimulusApp };
|
||||
4
src/StimulusBundle/assets/dist/loader.js
vendored
4
src/StimulusBundle/assets/dist/loader.js
vendored
@@ -1,5 +1,5 @@
|
||||
import { eagerControllers, isApplicationDebug, lazyControllers } from "./controllers.js";
|
||||
import { Application } from "@hotwired/stimulus";
|
||||
import { eagerControllers, isApplicationDebug, lazyControllers } from "./controllers.js";
|
||||
const controllerAttribute = "data-controller";
|
||||
const loadControllers = (application, eagerControllers, lazyControllers) => {
|
||||
for (const name in eagerControllers) registerController(name, eagerControllers[name], application);
|
||||
@@ -67,4 +67,4 @@ function extractControllerNamesFrom(element) {
|
||||
function canRegisterController(name, application) {
|
||||
return !application.router.modulesByIdentifier.has(name);
|
||||
}
|
||||
export { loadControllers, startStimulusApp };
|
||||
export { loadControllers, startStimulusApp };
|
||||
|
||||
2
src/Svelte/assets/dist/components.js
vendored
2
src/Svelte/assets/dist/components.js
vendored
@@ -1,2 +1,2 @@
|
||||
const components = {};
|
||||
export { components };
|
||||
export { components };
|
||||
|
||||
2
src/Svelte/assets/dist/loader.js
vendored
2
src/Svelte/assets/dist/loader.js
vendored
@@ -9,4 +9,4 @@ function registerSvelteControllerComponents(svelteComponents = components) {
|
||||
return component;
|
||||
};
|
||||
}
|
||||
export { registerSvelteControllerComponents };
|
||||
export { registerSvelteControllerComponents };
|
||||
|
||||
@@ -12,4 +12,4 @@ function registerSvelteControllerComponents(context) {
|
||||
return component;
|
||||
};
|
||||
}
|
||||
export { registerSvelteControllerComponents };
|
||||
export { registerSvelteControllerComponents };
|
||||
|
||||
2
src/Svelte/assets/dist/render_controller.js
vendored
2
src/Svelte/assets/dist/render_controller.js
vendored
@@ -43,4 +43,4 @@ _Class.values = {
|
||||
props: Object,
|
||||
intro: Boolean
|
||||
};
|
||||
export { _Class as default };
|
||||
export { _Class as default };
|
||||
|
||||
2
src/Swup/assets/dist/controller.js
vendored
2
src/Swup/assets/dist/controller.js
vendored
@@ -45,4 +45,4 @@ _Class.values = {
|
||||
debug: Boolean,
|
||||
mainElement: String
|
||||
};
|
||||
export { _Class as default };
|
||||
export { _Class as default };
|
||||
|
||||
2
src/TogglePassword/assets/dist/controller.js
vendored
2
src/TogglePassword/assets/dist/controller.js
vendored
@@ -67,4 +67,4 @@ _Class.values = {
|
||||
},
|
||||
buttonClasses: Array
|
||||
};
|
||||
export { _Class as default };
|
||||
export { _Class as default };
|
||||
|
||||
2
src/TogglePassword/assets/dist/style.min.css
vendored
2
src/TogglePassword/assets/dist/style.min.css
vendored
@@ -1 +1 @@
|
||||
.toggle-password-container{position:relative}.toggle-password-icon{width:1rem;height:1rem}.toggle-password-button{background-color:#0000;border:none;flex-direction:row;place-items:center;column-gap:.25rem;height:1rem;font-size:.875rem;line-height:1.25rem;display:flex;position:absolute;top:-1.25rem;right:.5rem}
|
||||
.toggle-password-container{position:relative}.toggle-password-icon{width:1rem;height:1rem}.toggle-password-button{background-color:#0000;border:none;flex-direction:row;place-items:center;column-gap:.25rem;height:1rem;font-size:.875rem;line-height:1.25rem;display:flex;position:absolute;top:-1.25rem;right:.5rem}
|
||||
|
||||
@@ -192,4 +192,4 @@ function createTranslator({ messages, locale = getDefaultLocale(), localeFallbac
|
||||
trans
|
||||
};
|
||||
}
|
||||
export { createTranslator, getDefaultLocale };
|
||||
export { createTranslator, getDefaultLocale };
|
||||
|
||||
1
src/Turbo/assets/dist/turbo_controller.d.ts
vendored
1
src/Turbo/assets/dist/turbo_controller.d.ts
vendored
@@ -1,4 +1,3 @@
|
||||
import { Controller } from "@hotwired/stimulus";
|
||||
import "@hotwired/turbo";
|
||||
declare class export_default extends Controller {}
|
||||
export { export_default as default };
|
||||
2
src/Turbo/assets/dist/turbo_controller.js
vendored
2
src/Turbo/assets/dist/turbo_controller.js
vendored
@@ -1,4 +1,4 @@
|
||||
import { Controller } from "@hotwired/stimulus";
|
||||
import "@hotwired/turbo";
|
||||
var turbo_controller_default = class extends Controller {};
|
||||
export { turbo_controller_default as default };
|
||||
export { turbo_controller_default as default };
|
||||
|
||||
@@ -32,4 +32,4 @@ _Class.values = {
|
||||
hub: String,
|
||||
withCredentials: Boolean
|
||||
};
|
||||
export { _Class as default };
|
||||
export { _Class as default };
|
||||
|
||||
2
src/Typed/assets/dist/controller.js
vendored
2
src/Typed/assets/dist/controller.js
vendored
@@ -86,4 +86,4 @@ _Class.values = {
|
||||
default: "html"
|
||||
}
|
||||
};
|
||||
export { _Class as default };
|
||||
export { _Class as default };
|
||||
|
||||
2
src/Vue/assets/dist/components.js
vendored
2
src/Vue/assets/dist/components.js
vendored
@@ -1,2 +1,2 @@
|
||||
const components = {};
|
||||
export { components };
|
||||
export { components };
|
||||
|
||||
2
src/Vue/assets/dist/loader.d.ts
vendored
2
src/Vue/assets/dist/loader.d.ts
vendored
@@ -1,5 +1,5 @@
|
||||
import { ComponentCollection } from "./components.js";
|
||||
import { Component } from "vue";
|
||||
import { ComponentCollection } from "./components.js";
|
||||
declare global {
|
||||
function resolveVueComponent(name: string): Component;
|
||||
interface Window {
|
||||
|
||||
2
src/Vue/assets/dist/loader.js
vendored
2
src/Vue/assets/dist/loader.js
vendored
@@ -12,4 +12,4 @@ function registerVueControllerComponents(vueControllers = components) {
|
||||
return loadComponent(name);
|
||||
};
|
||||
}
|
||||
export { registerVueControllerComponents };
|
||||
export { registerVueControllerComponents };
|
||||
|
||||
2
src/Vue/assets/dist/register_controller.js
vendored
2
src/Vue/assets/dist/register_controller.js
vendored
@@ -27,4 +27,4 @@ function registerVueControllerComponents(context) {
|
||||
return loadComponent(name);
|
||||
};
|
||||
}
|
||||
export { registerVueControllerComponents };
|
||||
export { registerVueControllerComponents };
|
||||
|
||||
2
src/Vue/assets/dist/render_controller.js
vendored
2
src/Vue/assets/dist/render_controller.js
vendored
@@ -41,4 +41,4 @@ _Class.values = {
|
||||
component: String,
|
||||
props: Object
|
||||
};
|
||||
export { _Class as default };
|
||||
export { _Class as default };
|
||||
|
||||
Reference in New Issue
Block a user