less 5.0.0-alpha.1 → 5.0.0-alpha.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -6
- package/V5-STATUS.md +71 -0
- package/bin/lessc +130 -14
- package/dist/less-browser-dev.js +2550 -0
- package/dist/less-node.cjs +193 -100
- package/lib/browser-dev.js +86 -0
- package/lib/lessc-helper.js +15 -3
- package/lib/options.d.ts +39 -3
- package/lib/options.js +104 -22
- package/package.json +14 -12
package/lib/options.js
CHANGED
|
@@ -5,27 +5,19 @@
|
|
|
5
5
|
|
|
6
6
|
import lessPlugin from '@jesscss/plugin-less';
|
|
7
7
|
import { lessCompatPlugin } from '@jesscss/plugin-less-compat';
|
|
8
|
+
import { logger } from './logger.js';
|
|
8
9
|
|
|
9
10
|
const unsupportedAlphaOptions = new Map([
|
|
10
|
-
['sourceMap', 'source maps are not supported'],
|
|
11
|
-
['sourceMapFilename', 'source maps are not supported'],
|
|
12
|
-
['sourceMapRootpath', 'source maps are not supported'],
|
|
13
|
-
['sourceMapBasepath', 'source maps are not supported'],
|
|
14
|
-
['sourceMapURL', 'source maps are not supported'],
|
|
15
|
-
['sourceMapFileInline', 'source maps are not supported'],
|
|
16
11
|
['globalVars', 'global variable injection is not supported'],
|
|
17
12
|
['modifyVars', 'modify-var injection is not supported'],
|
|
18
|
-
['strictUnits', 'strict unit mode is not supported'],
|
|
19
|
-
['rootpath', 'URL rootpath rewriting is not supported'],
|
|
20
|
-
['rewriteUrls', 'URL rewriting is not supported'],
|
|
21
|
-
['urlArgs', 'URL argument rewriting is not supported'],
|
|
22
13
|
['javascriptEnabled', 'JavaScript evaluation is not supported'],
|
|
23
|
-
['compress', 'compressed output is not supported'],
|
|
24
14
|
]);
|
|
25
15
|
|
|
26
16
|
function validateAlphaOptions(options) {
|
|
27
17
|
for (const [name, reason] of unsupportedAlphaOptions) {
|
|
28
|
-
|
|
18
|
+
// A falsy value is the 4.x default ("off") and requests nothing, so it is
|
|
19
|
+
// a no-op here; only an actual request for the feature is unsupported.
|
|
20
|
+
if (options[name]) {
|
|
29
21
|
throw new Error(`${name} is not supported: ${reason}`);
|
|
30
22
|
}
|
|
31
23
|
}
|
|
@@ -62,6 +54,55 @@ function stableStringify(value, seen = new WeakSet()) {
|
|
|
62
54
|
return `{${entries.join(',')}}`;
|
|
63
55
|
}
|
|
64
56
|
|
|
57
|
+
/**
|
|
58
|
+
* `collapseNesting` accepts `false` (keep authored nesting — the v5 default),
|
|
59
|
+
* `'native'` (CSS Nesting desugaring: parent wrapped in `:is()`, child selector
|
|
60
|
+
* lists distributed, specificity-faithful), `'compact'` (like `'native'` but
|
|
61
|
+
* also folds same-combinator descendant runs into one `:is()`), or the
|
|
62
|
+
* deprecated boolean `true` (alias for `'native'`). Anything else is rejected.
|
|
63
|
+
* @param {unknown} value
|
|
64
|
+
* @returns {boolean|'native'|'compact'}
|
|
65
|
+
*/
|
|
66
|
+
function resolveCollapseNesting(value) {
|
|
67
|
+
if (value === false || value === true || value === 'native' || value === 'compact') {
|
|
68
|
+
return value;
|
|
69
|
+
}
|
|
70
|
+
throw new Error(
|
|
71
|
+
`collapseNesting must be false, 'native', 'compact', or true `
|
|
72
|
+
+ `(deprecated alias for 'native'); got ${JSON.stringify(value)}`
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Build the compiler's `output.sourceMap` value from Less options. Source maps
|
|
78
|
+
* are enabled when `sourceMap` is truthy; the object form (or the flat legacy
|
|
79
|
+
* `sourceMap*` options) configures the details. Returns `undefined` when no
|
|
80
|
+
* source map is requested.
|
|
81
|
+
* @param {import('./options.js').LessRenderOptions} opts
|
|
82
|
+
* @returns {undefined | true | Record<string, unknown>}
|
|
83
|
+
*/
|
|
84
|
+
function resolveSourceMap(opts) {
|
|
85
|
+
if (!opts.sourceMap) {
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
const config = (typeof opts.sourceMap === 'object' && opts.sourceMap !== null)
|
|
89
|
+
? { ...opts.sourceMap }
|
|
90
|
+
: {};
|
|
91
|
+
// Fold the flat legacy `sourceMap*` options into the object form the compiler
|
|
92
|
+
// reads; an explicit object sub-option wins over its flat alias.
|
|
93
|
+
const flat = [
|
|
94
|
+
'sourceMapURL', 'sourceMapFilename', 'sourceMapFullFilename',
|
|
95
|
+
'sourceMapRootpath', 'sourceMapBasepath', 'sourceMapFileInline',
|
|
96
|
+
'sourceMapOutputFilename', 'outputSourceFiles', 'disableSourcemapAnnotation'
|
|
97
|
+
];
|
|
98
|
+
for (const key of flat) {
|
|
99
|
+
if (opts[key] !== undefined && config[key] === undefined) {
|
|
100
|
+
config[key] = opts[key];
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return Object.keys(config).length > 0 ? config : true;
|
|
104
|
+
}
|
|
105
|
+
|
|
65
106
|
/**
|
|
66
107
|
* Map Less render options to Jess compiler config.
|
|
67
108
|
* @param {import('./options.js').LessRenderOptions} [options] Less-style options
|
|
@@ -81,26 +122,60 @@ export function createLessOptions(options) {
|
|
|
81
122
|
math === 2 || math === 'parens' || math === 'strict' ? 'parens' :
|
|
82
123
|
'parens-division';
|
|
83
124
|
|
|
84
|
-
|
|
125
|
+
// `unitMode` is the option ('loose' | 'preserve' | 'strict'); `strictUnits`
|
|
126
|
+
// is its deprecated boolean alias: true → 'strict'; false means "not strict",
|
|
127
|
+
// i.e. the default ('preserve') — never the Less 4.x 'loose' fold, which only
|
|
128
|
+
// an explicit `unitMode: 'loose'` selects. Any use warns so the mapping is
|
|
129
|
+
// never discovered by staring at output. Left unset so the compiler default applies.
|
|
130
|
+
const unitMode = opts.unitMode !== undefined ? opts.unitMode
|
|
131
|
+
: opts.strictUnits === true ? 'strict'
|
|
132
|
+
: undefined;
|
|
133
|
+
if (opts.strictUnits !== undefined && opts.unitMode === undefined) {
|
|
134
|
+
logger.warn(
|
|
135
|
+
`strictUnits is deprecated; use unitMode. strictUnits: ${String(opts.strictUnits)} now means `
|
|
136
|
+
+ `unitMode: '${unitMode ?? 'preserve'}'${opts.strictUnits ? '' : " (Less 4.x unit folding is unitMode: 'loose')"}`
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// URL rewriting lives on the Less plugin (it rewrites `url(...)` during
|
|
141
|
+
// serialization), not in `output`. Only forward keys the caller set so the
|
|
142
|
+
// plugin's own v5 defaults apply otherwise.
|
|
143
|
+
const lessPluginOptions = {};
|
|
144
|
+
if (opts.rootpath !== undefined) lessPluginOptions.rootpath = opts.rootpath;
|
|
145
|
+
if (opts.rewriteUrls !== undefined) lessPluginOptions.rewriteUrls = opts.rewriteUrls;
|
|
146
|
+
if (opts.urlArgs !== undefined) lessPluginOptions.urlArgs = opts.urlArgs;
|
|
147
|
+
|
|
148
|
+
const plugins = [lessPlugin(lessPluginOptions)];
|
|
85
149
|
if (!skipLessCompat) {
|
|
86
150
|
plugins.push(lessCompatPlugin({ plugins: lessPlugins }));
|
|
87
151
|
}
|
|
88
152
|
|
|
153
|
+
// The projection/serialization options the compiler reads off `output`:
|
|
154
|
+
// `collapseNesting` (nesting flatten mode), `compress` (minified output), and
|
|
155
|
+
// `sourceMap`. Emitted as a single file-less array entry so an explicit render
|
|
156
|
+
// option overrides a file-local styles.config for every key (the config merge
|
|
157
|
+
// appends it as the override default); left `{}` when the caller set none.
|
|
158
|
+
const outputEntry = {};
|
|
159
|
+
if (opts.collapseNesting !== undefined) {
|
|
160
|
+
outputEntry.collapseNesting = resolveCollapseNesting(opts.collapseNesting);
|
|
161
|
+
}
|
|
162
|
+
if (opts.compress !== undefined) {
|
|
163
|
+
outputEntry.compress = opts.compress;
|
|
164
|
+
}
|
|
165
|
+
const sourceMap = resolveSourceMap(opts);
|
|
166
|
+
if (sourceMap !== undefined) {
|
|
167
|
+
outputEntry.sourceMap = sourceMap;
|
|
168
|
+
}
|
|
169
|
+
const output = Object.keys(outputEntry).length > 0 ? [outputEntry] : {};
|
|
170
|
+
|
|
89
171
|
const configOptions = {
|
|
90
172
|
compile: {
|
|
91
173
|
searchPaths: opts.paths || [],
|
|
92
174
|
mathMode,
|
|
175
|
+
...(unitMode !== undefined && { unitMode }),
|
|
93
176
|
plugins,
|
|
94
177
|
},
|
|
95
|
-
|
|
96
|
-
// switch requests flattened CSS. Keep that public Less option at the
|
|
97
|
-
// wrapper boundary; Jess owns the one renderer and its output mode.
|
|
98
|
-
// A file's styles.config may use an output array. A file-less output entry
|
|
99
|
-
// is the compiler's documented per-render override for that shape, so an
|
|
100
|
-
// explicit public Less option remains authoritative over fixture config.
|
|
101
|
-
output: Object.prototype.hasOwnProperty.call(opts, 'collapseNesting')
|
|
102
|
-
? [{ collapseNesting: opts.collapseNesting === true }]
|
|
103
|
-
: {},
|
|
178
|
+
output,
|
|
104
179
|
language: {},
|
|
105
180
|
};
|
|
106
181
|
|
|
@@ -129,6 +204,13 @@ export function mapRenderResult(result, options) {
|
|
|
129
204
|
css: result.css ?? '',
|
|
130
205
|
};
|
|
131
206
|
|
|
207
|
+
// Less 4.x returns the source map as `result.map` (a JSON string) when one was
|
|
208
|
+
// requested; forward it so `less.render(src, { sourceMap: true })` behaves the
|
|
209
|
+
// same. The compiler writes the `sourceMappingURL` annotation into `css` itself.
|
|
210
|
+
if (result.map !== undefined) {
|
|
211
|
+
out.map = result.map;
|
|
212
|
+
}
|
|
213
|
+
|
|
132
214
|
if (result.imports && Array.isArray(result.imports)) {
|
|
133
215
|
out.imports = result.imports;
|
|
134
216
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "less",
|
|
3
|
-
"version": "5.0.0-alpha.
|
|
3
|
+
"version": "5.0.0-alpha.11",
|
|
4
4
|
"description": "Leaner CSS",
|
|
5
5
|
"homepage": "http://lesscss.org",
|
|
6
6
|
"author": {
|
|
@@ -45,14 +45,15 @@
|
|
|
45
45
|
"!lib/**/*.map",
|
|
46
46
|
"dist",
|
|
47
47
|
"index.cjs",
|
|
48
|
-
"README.md"
|
|
48
|
+
"README.md",
|
|
49
|
+
"V5-STATUS.md"
|
|
49
50
|
],
|
|
50
51
|
"engines": {
|
|
51
52
|
"node": "^20.19.0 || >=22.12.0"
|
|
52
53
|
},
|
|
53
54
|
"scripts": {
|
|
54
55
|
"quicktest": "npm run test:legacy-node",
|
|
55
|
-
"test:alpha": "npm run typecheck && npm run build && npm run test:lessc && node test/jess-alpha-fast-path.mjs && node test/alpha-support.mjs && node test/alpha-fixtures.mjs",
|
|
56
|
+
"test:alpha": "npm run typecheck && npm run build && npm run test:lessc && node test/jess-alpha-fast-path.mjs && node test/alpha-support.mjs && node test/alpha-sourcemaps.mjs && node test/alpha-fixtures.mjs",
|
|
56
57
|
"test:lessc": "node test/lessc-alpha.mjs",
|
|
57
58
|
"test": "npm run test:alpha",
|
|
58
59
|
"test:module": "node test/test-es6.js && node test/test-cjs.cjs",
|
|
@@ -63,9 +64,10 @@
|
|
|
63
64
|
"lint:fix": "eslint '**/*.{ts,js}' --fix",
|
|
64
65
|
"typecheck": "tsc --noEmit",
|
|
65
66
|
"build": "node build/rollup.js --dist",
|
|
67
|
+
"build:browser": "node build/browser-dev.mjs --minify",
|
|
66
68
|
"benchmark": "node benchmark/benchmark-runner.cjs",
|
|
67
69
|
"benchmark:all": "node benchmark/run-and-compare.mjs",
|
|
68
|
-
"prepublishOnly": "npm run typecheck && npm run build && npm run test:lessc"
|
|
70
|
+
"prepublishOnly": "npm run typecheck && npm run build && npm run build:browser && npm run test:lessc"
|
|
69
71
|
},
|
|
70
72
|
"devDependencies": {
|
|
71
73
|
"@less/test-data": "workspace:*",
|
|
@@ -83,6 +85,7 @@
|
|
|
83
85
|
"chalk": "^4.1.2",
|
|
84
86
|
"cosmiconfig": "~9.0.0",
|
|
85
87
|
"cross-env": "^7.0.3",
|
|
88
|
+
"esbuild": "^0.25.0",
|
|
86
89
|
"eslint": "^7.29.0",
|
|
87
90
|
"fs-extra": "^8.1.0",
|
|
88
91
|
"glob": "~11.0.3",
|
|
@@ -139,16 +142,15 @@
|
|
|
139
142
|
"rawcurrent": "https://raw.github.com/less/less.js/v",
|
|
140
143
|
"sourcearchive": "https://github.com/less/less.js/archive/v",
|
|
141
144
|
"dependencies": {
|
|
142
|
-
"@jesscss/compiler": "2.0.0-alpha.
|
|
143
|
-
"@jesscss/core": "2.0.0-alpha.
|
|
144
|
-
"@jesscss/plugin-less": "2.0.0-alpha.
|
|
145
|
-
"@jesscss/plugin-less-compat": "2.0.0-alpha.
|
|
146
|
-
"@jesscss/plugin-node-modules": "2.0.0-alpha.
|
|
147
|
-
"parse-node-version": "^1.0.1"
|
|
148
|
-
"parseman": "^0.41.0"
|
|
145
|
+
"@jesscss/compiler": "2.0.0-alpha.24",
|
|
146
|
+
"@jesscss/core": "2.0.0-alpha.24",
|
|
147
|
+
"@jesscss/plugin-less": "2.0.0-alpha.24",
|
|
148
|
+
"@jesscss/plugin-less-compat": "2.0.0-alpha.24",
|
|
149
|
+
"@jesscss/plugin-node-modules": "2.0.0-alpha.24",
|
|
150
|
+
"parse-node-version": "^1.0.1"
|
|
149
151
|
},
|
|
150
152
|
"peerDependencies": {
|
|
151
|
-
"@jesscss/plugin-js": "2.0.0-alpha.
|
|
153
|
+
"@jesscss/plugin-js": "2.0.0-alpha.24"
|
|
152
154
|
},
|
|
153
155
|
"peerDependenciesMeta": {
|
|
154
156
|
"@jesscss/plugin-js": {
|