lvyjs 0.2.22 → 0.2.23
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/lib/main.js +33 -31
- package/lib/new-loader/content.js +17 -17
- package/lib/new-loader/postcss.js +170 -172
- package/lib/postcss.js +170 -172
- package/package.json +1 -1
package/lib/main.js
CHANGED
|
@@ -1,38 +1,40 @@
|
|
|
1
|
-
import module from 'node:module'
|
|
2
|
-
import { MessageChannel } from 'node:worker_threads'
|
|
3
|
-
import { postCSS } from './postcss.js'
|
|
4
|
-
import { stylesRegExp, assetsRegExp } from './config.js'
|
|
1
|
+
import module from 'node:module'
|
|
2
|
+
import { MessageChannel } from 'node:worker_threads'
|
|
3
|
+
import { postCSS } from './postcss.js'
|
|
4
|
+
import { stylesRegExp, assetsRegExp } from './config.js'
|
|
5
5
|
|
|
6
6
|
if (!module.register) {
|
|
7
|
-
|
|
7
|
+
throw new Error(
|
|
8
|
+
`This version of Node.js (${process.version}) does not support module.register(). Please upgrade to Node v18.19 or v20.6 and above.`
|
|
9
|
+
)
|
|
8
10
|
}
|
|
9
|
-
const { port1, port2 } = new MessageChannel()
|
|
10
|
-
const cache = {}
|
|
11
|
+
const { port1, port2 } = new MessageChannel()
|
|
12
|
+
const cache = {}
|
|
11
13
|
port1.on('message', msg => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
14
|
+
if (msg.type == 'CSS_MODULE_GENERATED') {
|
|
15
|
+
const { from, to } = msg.payload
|
|
16
|
+
if (!cache[from]) {
|
|
17
|
+
const formPath = decodeURIComponent(from)
|
|
18
|
+
postCSS(formPath, to)
|
|
19
|
+
// postCSS(from, to)
|
|
20
|
+
cache[from] = true
|
|
20
21
|
}
|
|
21
|
-
}
|
|
22
|
+
}
|
|
23
|
+
})
|
|
22
24
|
// port1.unref()
|
|
23
25
|
module.register('./loader.js', {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
})
|
|
26
|
+
parentURL: import.meta.url,
|
|
27
|
+
data: {
|
|
28
|
+
port: port2,
|
|
29
|
+
lvyConfig: {
|
|
30
|
+
alias: global.lvyConfig?.alias,
|
|
31
|
+
assets: global.lvyConfig?.assets ?? {
|
|
32
|
+
filter: assetsRegExp
|
|
33
|
+
},
|
|
34
|
+
styles: global.lvyConfig?.styles ?? {
|
|
35
|
+
filter: stylesRegExp
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
transferList: [port2]
|
|
40
|
+
})
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import crypto from 'node:crypto'
|
|
2
|
-
import { convertPath } from '../config.js'
|
|
1
|
+
import crypto from 'node:crypto'
|
|
2
|
+
import { convertPath } from '../config.js'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* 生成静态资源模块内容
|
|
6
6
|
* @param relativePath 相对路径
|
|
7
7
|
*/
|
|
8
|
-
const generateModuleContent =
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
8
|
+
const generateModuleContent = relativePath => {
|
|
9
|
+
const baseURL = decodeURIComponent(relativePath)
|
|
10
|
+
const contents = [
|
|
11
|
+
`const reg = ['win32'].includes(process.platform) ? /^file:\\/\\/\\// : /^file:\\/\\// ;`,
|
|
12
|
+
`const fileUrl = import.meta.resolve('${convertPath(baseURL)}').replace(reg, '');`,
|
|
13
|
+
'export default fileUrl;'
|
|
14
|
+
].join('\n')
|
|
15
|
+
return contents
|
|
16
|
+
}
|
|
17
17
|
/**
|
|
18
18
|
* 生成随机文件名
|
|
19
19
|
*/
|
|
20
|
-
const getRandomName =
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
20
|
+
const getRandomName = str => {
|
|
21
|
+
const hash = crypto.createHash('md5')
|
|
22
|
+
hash.update(str)
|
|
23
|
+
return hash.digest('hex')
|
|
24
|
+
}
|
|
25
25
|
|
|
26
|
-
export { generateModuleContent, getRandomName }
|
|
26
|
+
export { generateModuleContent, getRandomName }
|
|
@@ -1,36 +1,42 @@
|
|
|
1
|
-
import fs from 'fs'
|
|
2
|
-
import postcss from 'postcss'
|
|
3
|
-
import { createRequire } from 'module'
|
|
4
|
-
import { join, resolve, dirname, isAbsolute } from 'path'
|
|
5
|
-
import { convertPath, createAlias } from '../config.js'
|
|
1
|
+
import fs from 'fs'
|
|
2
|
+
import postcss from 'postcss'
|
|
3
|
+
import { createRequire } from 'module'
|
|
4
|
+
import { join, resolve, dirname, isAbsolute } from 'path'
|
|
5
|
+
import { convertPath, createAlias } from '../config.js'
|
|
6
6
|
|
|
7
|
-
const require = createRequire(import.meta.url)
|
|
7
|
+
const require = createRequire(import.meta.url)
|
|
8
8
|
const config = {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
9
|
+
css: null,
|
|
10
|
+
sass: null,
|
|
11
|
+
less: null,
|
|
12
|
+
scss: null
|
|
13
|
+
}
|
|
14
14
|
function LessAliasPlugin(aliases) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
15
|
+
return {
|
|
16
|
+
install: function (less, pluginManager) {
|
|
17
|
+
const AliasFileManager = new less.FileManager()
|
|
18
|
+
AliasFileManager.loadFile = function (filename, currentDirectory, options, environment) {
|
|
19
|
+
// 替换路径中的别名
|
|
20
|
+
for (const alias in aliases) {
|
|
21
|
+
if (filename.startsWith(alias)) {
|
|
22
|
+
filename = filename.replace(alias, aliases[alias])
|
|
23
|
+
break
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const fullPath = isAbsolute(filename) ? filename : resolve(currentDirectory, filename)
|
|
27
|
+
return less.FileManager.prototype.loadFile.call(
|
|
28
|
+
this,
|
|
29
|
+
fullPath,
|
|
30
|
+
currentDirectory,
|
|
31
|
+
options,
|
|
32
|
+
environment
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
// 注册自定义文件管理器
|
|
36
|
+
pluginManager.addFileManager(AliasFileManager)
|
|
37
|
+
},
|
|
38
|
+
minVersion: [3, 0] // 支持的最低 LESS 版本
|
|
39
|
+
}
|
|
34
40
|
}
|
|
35
41
|
/**
|
|
36
42
|
*
|
|
@@ -39,95 +45,92 @@ function LessAliasPlugin(aliases) {
|
|
|
39
45
|
* @returns
|
|
40
46
|
*/
|
|
41
47
|
const loadPostcssConfig = (configPath, typing) => {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
const plugins = [];
|
|
48
|
-
let aliasEntries = [];
|
|
49
|
-
if (typeof global.lvyConfig?.alias != 'boolean') {
|
|
50
|
-
aliasEntries = global.lvyConfig.alias?.entries || [];
|
|
51
|
-
}
|
|
52
|
-
const includeKeys = ['postcss-import', 'postcss-url', 'autoprefixer'];
|
|
53
|
-
//
|
|
54
|
-
if (aliasEntries.length > 0) {
|
|
55
|
-
// 创建 postcss-import 插件并配置别名解析
|
|
56
|
-
try {
|
|
57
|
-
plugins.push(require('postcss-import')({
|
|
58
|
-
resolve: (id, basedir) => {
|
|
59
|
-
// 检查别名
|
|
60
|
-
for (const entry of aliasEntries) {
|
|
61
|
-
if (id.startsWith(entry.find)) {
|
|
62
|
-
const aliasedPath = id.replace(entry.find, entry.replacement);
|
|
63
|
-
return convertPath(resolve(basedir, aliasedPath));
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
return id; // 默认返回原始路径
|
|
67
|
-
}
|
|
68
|
-
}));
|
|
69
|
-
}
|
|
70
|
-
catch (err) {
|
|
71
|
-
console.error(err);
|
|
72
|
-
}
|
|
73
|
-
try {
|
|
74
|
-
plugins.push(require('postcss-url')({
|
|
75
|
-
url: asset => {
|
|
76
|
-
// 使用 resolve 逻辑处理 URL
|
|
77
|
-
for (const entry of aliasEntries) {
|
|
78
|
-
if (asset.url.startsWith(entry.find)) {
|
|
79
|
-
const aliasedPath = asset.url.replace(entry.find, entry.replacement);
|
|
80
|
-
return convertPath(aliasedPath);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return convertPath(asset.url);
|
|
84
|
-
}
|
|
85
|
-
}));
|
|
86
|
-
}
|
|
87
|
-
catch (err) {
|
|
88
|
-
console.error(err);
|
|
89
|
-
}
|
|
48
|
+
if (config[typing]) {
|
|
49
|
+
return {
|
|
50
|
+
plugins: config[typing]
|
|
90
51
|
}
|
|
91
|
-
|
|
92
|
-
|
|
52
|
+
}
|
|
53
|
+
const plugins = []
|
|
54
|
+
let aliasEntries = []
|
|
55
|
+
if (typeof global.lvyConfig?.alias != 'boolean') {
|
|
56
|
+
aliasEntries = global.lvyConfig.alias?.entries || []
|
|
57
|
+
}
|
|
58
|
+
const includeKeys = ['postcss-import', 'postcss-url', 'autoprefixer']
|
|
59
|
+
//
|
|
60
|
+
if (aliasEntries.length > 0) {
|
|
61
|
+
// 创建 postcss-import 插件并配置别名解析
|
|
62
|
+
try {
|
|
63
|
+
plugins.push(
|
|
64
|
+
require('postcss-import')({
|
|
65
|
+
resolve: (id, basedir) => {
|
|
66
|
+
// 检查别名
|
|
67
|
+
for (const entry of aliasEntries) {
|
|
68
|
+
if (id.startsWith(entry.find)) {
|
|
69
|
+
const aliasedPath = id.replace(entry.find, entry.replacement)
|
|
70
|
+
return convertPath(resolve(basedir, aliasedPath))
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return id // 默认返回原始路径
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
)
|
|
77
|
+
} catch (err) {
|
|
78
|
+
console.error(err)
|
|
93
79
|
}
|
|
94
80
|
try {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const pluginConfig = cfg.plugins[key];
|
|
105
|
-
const plugin = require(key);
|
|
106
|
-
if (typeof plugin === 'function') {
|
|
107
|
-
plugins.push(plugin(pluginConfig));
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
throw new Error(`插件 ${key} 不是有效的 PostCSS 插件函数`);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
catch (err) {
|
|
114
|
-
console.error(`加载 PostCSS 插件 ${key} 失败:`, err);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
81
|
+
plugins.push(
|
|
82
|
+
require('postcss-url')({
|
|
83
|
+
url: asset => {
|
|
84
|
+
// 使用 resolve 逻辑处理 URL
|
|
85
|
+
for (const entry of aliasEntries) {
|
|
86
|
+
if (asset.url.startsWith(entry.find)) {
|
|
87
|
+
const aliasedPath = asset.url.replace(entry.find, entry.replacement)
|
|
88
|
+
return convertPath(aliasedPath)
|
|
89
|
+
}
|
|
117
90
|
}
|
|
118
|
-
|
|
119
|
-
|
|
91
|
+
return convertPath(asset.url)
|
|
92
|
+
}
|
|
93
|
+
})
|
|
94
|
+
)
|
|
95
|
+
} catch (err) {
|
|
96
|
+
console.error(err)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
for (let i = 2; i < includeKeys.length; i++) {
|
|
100
|
+
plugins.push(require(includeKeys[i])({}))
|
|
101
|
+
}
|
|
102
|
+
try {
|
|
103
|
+
if (fs.existsSync(configPath)) {
|
|
104
|
+
const cfg = require(configPath)
|
|
105
|
+
// 添加其他插件
|
|
106
|
+
if (!Array.isArray(cfg.plugins)) {
|
|
107
|
+
const keys = Object.keys(cfg.plugins)
|
|
108
|
+
for (const key of keys) {
|
|
109
|
+
try {
|
|
110
|
+
if (includeKeys.includes(key)) continue
|
|
111
|
+
const pluginConfig = cfg.plugins[key]
|
|
112
|
+
const plugin = require(key)
|
|
113
|
+
if (typeof plugin === 'function') {
|
|
114
|
+
plugins.push(plugin(pluginConfig))
|
|
115
|
+
} else {
|
|
116
|
+
throw new Error(`插件 ${key} 不是有效的 PostCSS 插件函数`)
|
|
120
117
|
}
|
|
118
|
+
} catch (err) {
|
|
119
|
+
console.error(`加载 PostCSS 插件 ${key} 失败:`, err)
|
|
120
|
+
}
|
|
121
121
|
}
|
|
122
|
+
} else {
|
|
123
|
+
plugins.push(...cfg.plugins)
|
|
124
|
+
}
|
|
122
125
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
126
|
+
} catch (err) {
|
|
127
|
+
console.error('加载 PostCSS 配置失败:', err)
|
|
128
|
+
}
|
|
129
|
+
config[typing] = plugins
|
|
130
|
+
return {
|
|
131
|
+
plugins: config[typing]
|
|
132
|
+
}
|
|
133
|
+
}
|
|
131
134
|
/**
|
|
132
135
|
*
|
|
133
136
|
* @param inputPath
|
|
@@ -135,68 +138,63 @@ const loadPostcssConfig = (configPath, typing) => {
|
|
|
135
138
|
* @returns
|
|
136
139
|
*/
|
|
137
140
|
const postCSS = (inputPath, outputPath) => {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
141
|
+
const configPath = join(process.cwd(), 'postcss.config.cjs')
|
|
142
|
+
let typing = 'css'
|
|
143
|
+
let parser = undefined
|
|
144
|
+
if (/\.sass$/.test(inputPath)) {
|
|
145
|
+
typing = 'sass'
|
|
146
|
+
} else if (/\.less$/.test(inputPath)) {
|
|
147
|
+
typing = 'less'
|
|
148
|
+
} else if (/\.scss$/.test(inputPath)) {
|
|
149
|
+
typing = 'scss'
|
|
150
|
+
}
|
|
151
|
+
const postcssConfig = loadPostcssConfig(configPath, 'css')
|
|
152
|
+
if (!postcssConfig) return
|
|
153
|
+
const readAndProcessCSS = async () => {
|
|
154
|
+
let css = ''
|
|
155
|
+
if (typing === 'less') {
|
|
156
|
+
const less = require('less')
|
|
157
|
+
const lessResult = await less.render(fs.readFileSync(inputPath, 'utf-8'), {
|
|
158
|
+
filename: inputPath,
|
|
159
|
+
plugins: [LessAliasPlugin(createAlias(global.lvyConfig?.alias))] // 使用插件
|
|
160
|
+
})
|
|
161
|
+
css = lessResult.css
|
|
162
|
+
} else if (typing === 'sass' || typing === 'scss') {
|
|
163
|
+
const sass = require('sass')
|
|
164
|
+
const sassResult = sass.renderSync({ file: inputPath })
|
|
165
|
+
css = sassResult.css.toString()
|
|
166
|
+
} else {
|
|
167
|
+
css = fs.readFileSync(inputPath, 'utf-8')
|
|
143
168
|
}
|
|
144
|
-
|
|
145
|
-
|
|
169
|
+
fs.mkdirSync(dirname(outputPath), { recursive: true })
|
|
170
|
+
const result = await postcss(postcssConfig.plugins).process(css, {
|
|
171
|
+
parser: parser,
|
|
172
|
+
from: inputPath,
|
|
173
|
+
to: outputPath
|
|
174
|
+
})
|
|
175
|
+
fs.writeFileSync(outputPath, result.css)
|
|
176
|
+
if (result.warnings().length) {
|
|
177
|
+
result.warnings().forEach(warn => {
|
|
178
|
+
console.warn(warn.toString())
|
|
179
|
+
})
|
|
146
180
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
return;
|
|
153
|
-
const readAndProcessCSS = async () => {
|
|
154
|
-
let css = '';
|
|
155
|
-
if (typing === 'less') {
|
|
156
|
-
const less = require('less');
|
|
157
|
-
const lessResult = await less.render(fs.readFileSync(inputPath, 'utf-8'), {
|
|
158
|
-
filename: inputPath,
|
|
159
|
-
plugins: [LessAliasPlugin(createAlias(global.lvyConfig?.alias))] // 使用插件
|
|
160
|
-
});
|
|
161
|
-
css = lessResult.css;
|
|
162
|
-
}
|
|
163
|
-
else if (typing === 'sass' || typing === 'scss') {
|
|
164
|
-
const sass = require('sass');
|
|
165
|
-
const sassResult = sass.renderSync({ file: inputPath });
|
|
166
|
-
css = sassResult.css.toString();
|
|
167
|
-
}
|
|
168
|
-
else {
|
|
169
|
-
css = fs.readFileSync(inputPath, 'utf-8');
|
|
170
|
-
}
|
|
171
|
-
fs.mkdirSync(dirname(outputPath), { recursive: true });
|
|
172
|
-
const result = await postcss(postcssConfig.plugins).process(css, {
|
|
173
|
-
parser: parser,
|
|
174
|
-
from: inputPath,
|
|
175
|
-
to: outputPath
|
|
176
|
-
});
|
|
177
|
-
fs.writeFileSync(outputPath, result.css);
|
|
178
|
-
if (result.warnings().length) {
|
|
179
|
-
result.warnings().forEach(warn => {
|
|
180
|
-
console.warn(warn.toString());
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
const dependencies = result.messages
|
|
184
|
-
.filter(msg => msg.type === 'dependency')
|
|
185
|
-
.map(msg => msg.file);
|
|
186
|
-
for (const dep of dependencies) {
|
|
187
|
-
fs.watch(dep, eventType => {
|
|
188
|
-
if (eventType === 'change') {
|
|
189
|
-
readAndProcessCSS();
|
|
190
|
-
}
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
};
|
|
194
|
-
readAndProcessCSS();
|
|
195
|
-
fs.watch(inputPath, eventType => {
|
|
181
|
+
const dependencies = result.messages
|
|
182
|
+
.filter(msg => msg.type === 'dependency')
|
|
183
|
+
.map(msg => msg.file)
|
|
184
|
+
for (const dep of dependencies) {
|
|
185
|
+
fs.watch(dep, eventType => {
|
|
196
186
|
if (eventType === 'change') {
|
|
197
|
-
|
|
187
|
+
readAndProcessCSS()
|
|
198
188
|
}
|
|
199
|
-
|
|
200
|
-
}
|
|
189
|
+
})
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
readAndProcessCSS()
|
|
193
|
+
fs.watch(inputPath, eventType => {
|
|
194
|
+
if (eventType === 'change') {
|
|
195
|
+
readAndProcessCSS()
|
|
196
|
+
}
|
|
197
|
+
})
|
|
198
|
+
}
|
|
201
199
|
|
|
202
|
-
export { LessAliasPlugin as default, postCSS }
|
|
200
|
+
export { LessAliasPlugin as default, postCSS }
|
package/lib/postcss.js
CHANGED
|
@@ -1,36 +1,42 @@
|
|
|
1
|
-
import fs from 'fs'
|
|
2
|
-
import postcss from 'postcss'
|
|
3
|
-
import { createRequire } from 'module'
|
|
4
|
-
import { join, resolve, dirname, isAbsolute } from 'path'
|
|
5
|
-
import { convertPath, createAlias } from './config.js'
|
|
1
|
+
import fs from 'fs'
|
|
2
|
+
import postcss from 'postcss'
|
|
3
|
+
import { createRequire } from 'module'
|
|
4
|
+
import { join, resolve, dirname, isAbsolute } from 'path'
|
|
5
|
+
import { convertPath, createAlias } from './config.js'
|
|
6
6
|
|
|
7
|
-
const require = createRequire(import.meta.url)
|
|
7
|
+
const require = createRequire(import.meta.url)
|
|
8
8
|
const config = {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
9
|
+
css: null,
|
|
10
|
+
sass: null,
|
|
11
|
+
less: null,
|
|
12
|
+
scss: null
|
|
13
|
+
}
|
|
14
14
|
function LessAliasPlugin(aliases) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
15
|
+
return {
|
|
16
|
+
install: function (less, pluginManager) {
|
|
17
|
+
const AliasFileManager = new less.FileManager()
|
|
18
|
+
AliasFileManager.loadFile = function (filename, currentDirectory, options, environment) {
|
|
19
|
+
// 替换路径中的别名
|
|
20
|
+
for (const alias in aliases) {
|
|
21
|
+
if (filename.startsWith(alias)) {
|
|
22
|
+
filename = filename.replace(alias, aliases[alias])
|
|
23
|
+
break
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const fullPath = isAbsolute(filename) ? filename : resolve(currentDirectory, filename)
|
|
27
|
+
return less.FileManager.prototype.loadFile.call(
|
|
28
|
+
this,
|
|
29
|
+
fullPath,
|
|
30
|
+
currentDirectory,
|
|
31
|
+
options,
|
|
32
|
+
environment
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
// 注册自定义文件管理器
|
|
36
|
+
pluginManager.addFileManager(AliasFileManager)
|
|
37
|
+
},
|
|
38
|
+
minVersion: [3, 0] // 支持的最低 LESS 版本
|
|
39
|
+
}
|
|
34
40
|
}
|
|
35
41
|
/**
|
|
36
42
|
*
|
|
@@ -39,95 +45,92 @@ function LessAliasPlugin(aliases) {
|
|
|
39
45
|
* @returns
|
|
40
46
|
*/
|
|
41
47
|
const loadPostcssConfig = (configPath, typing) => {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
const plugins = [];
|
|
48
|
-
let aliasEntries = [];
|
|
49
|
-
if (typeof global.lvyConfig?.alias != 'boolean') {
|
|
50
|
-
aliasEntries = global.lvyConfig.alias?.entries || [];
|
|
51
|
-
}
|
|
52
|
-
const includeKeys = ['postcss-import', 'postcss-url', 'autoprefixer'];
|
|
53
|
-
//
|
|
54
|
-
if (aliasEntries.length > 0) {
|
|
55
|
-
// 创建 postcss-import 插件并配置别名解析
|
|
56
|
-
try {
|
|
57
|
-
plugins.push(require('postcss-import')({
|
|
58
|
-
resolve: (id, basedir) => {
|
|
59
|
-
// 检查别名
|
|
60
|
-
for (const entry of aliasEntries) {
|
|
61
|
-
if (id.startsWith(entry.find)) {
|
|
62
|
-
const aliasedPath = id.replace(entry.find, entry.replacement);
|
|
63
|
-
return convertPath(resolve(basedir, aliasedPath));
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
return id; // 默认返回原始路径
|
|
67
|
-
}
|
|
68
|
-
}));
|
|
69
|
-
}
|
|
70
|
-
catch (err) {
|
|
71
|
-
console.error(err);
|
|
72
|
-
}
|
|
73
|
-
try {
|
|
74
|
-
plugins.push(require('postcss-url')({
|
|
75
|
-
url: asset => {
|
|
76
|
-
// 使用 resolve 逻辑处理 URL
|
|
77
|
-
for (const entry of aliasEntries) {
|
|
78
|
-
if (asset.url.startsWith(entry.find)) {
|
|
79
|
-
const aliasedPath = asset.url.replace(entry.find, entry.replacement);
|
|
80
|
-
return convertPath(aliasedPath);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return convertPath(asset.url);
|
|
84
|
-
}
|
|
85
|
-
}));
|
|
86
|
-
}
|
|
87
|
-
catch (err) {
|
|
88
|
-
console.error(err);
|
|
89
|
-
}
|
|
48
|
+
if (config[typing]) {
|
|
49
|
+
return {
|
|
50
|
+
plugins: config[typing]
|
|
90
51
|
}
|
|
91
|
-
|
|
92
|
-
|
|
52
|
+
}
|
|
53
|
+
const plugins = []
|
|
54
|
+
let aliasEntries = []
|
|
55
|
+
if (typeof global.lvyConfig?.alias != 'boolean') {
|
|
56
|
+
aliasEntries = global.lvyConfig.alias?.entries || []
|
|
57
|
+
}
|
|
58
|
+
const includeKeys = ['postcss-import', 'postcss-url', 'autoprefixer']
|
|
59
|
+
//
|
|
60
|
+
if (aliasEntries.length > 0) {
|
|
61
|
+
// 创建 postcss-import 插件并配置别名解析
|
|
62
|
+
try {
|
|
63
|
+
plugins.push(
|
|
64
|
+
require('postcss-import')({
|
|
65
|
+
resolve: (id, basedir) => {
|
|
66
|
+
// 检查别名
|
|
67
|
+
for (const entry of aliasEntries) {
|
|
68
|
+
if (id.startsWith(entry.find)) {
|
|
69
|
+
const aliasedPath = id.replace(entry.find, entry.replacement)
|
|
70
|
+
return convertPath(resolve(basedir, aliasedPath))
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return id // 默认返回原始路径
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
)
|
|
77
|
+
} catch (err) {
|
|
78
|
+
console.error(err)
|
|
93
79
|
}
|
|
94
80
|
try {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const pluginConfig = cfg.plugins[key];
|
|
105
|
-
const plugin = require(key);
|
|
106
|
-
if (typeof plugin === 'function') {
|
|
107
|
-
plugins.push(plugin(pluginConfig));
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
throw new Error(`插件 ${key} 不是有效的 PostCSS 插件函数`);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
catch (err) {
|
|
114
|
-
console.error(`加载 PostCSS 插件 ${key} 失败:`, err);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
81
|
+
plugins.push(
|
|
82
|
+
require('postcss-url')({
|
|
83
|
+
url: asset => {
|
|
84
|
+
// 使用 resolve 逻辑处理 URL
|
|
85
|
+
for (const entry of aliasEntries) {
|
|
86
|
+
if (asset.url.startsWith(entry.find)) {
|
|
87
|
+
const aliasedPath = asset.url.replace(entry.find, entry.replacement)
|
|
88
|
+
return convertPath(aliasedPath)
|
|
89
|
+
}
|
|
117
90
|
}
|
|
118
|
-
|
|
119
|
-
|
|
91
|
+
return convertPath(asset.url)
|
|
92
|
+
}
|
|
93
|
+
})
|
|
94
|
+
)
|
|
95
|
+
} catch (err) {
|
|
96
|
+
console.error(err)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
for (let i = 2; i < includeKeys.length; i++) {
|
|
100
|
+
plugins.push(require(includeKeys[i])({}))
|
|
101
|
+
}
|
|
102
|
+
try {
|
|
103
|
+
if (fs.existsSync(configPath)) {
|
|
104
|
+
const cfg = require(configPath)
|
|
105
|
+
// 添加其他插件
|
|
106
|
+
if (!Array.isArray(cfg.plugins)) {
|
|
107
|
+
const keys = Object.keys(cfg.plugins)
|
|
108
|
+
for (const key of keys) {
|
|
109
|
+
try {
|
|
110
|
+
if (includeKeys.includes(key)) continue
|
|
111
|
+
const pluginConfig = cfg.plugins[key]
|
|
112
|
+
const plugin = require(key)
|
|
113
|
+
if (typeof plugin === 'function') {
|
|
114
|
+
plugins.push(plugin(pluginConfig))
|
|
115
|
+
} else {
|
|
116
|
+
throw new Error(`插件 ${key} 不是有效的 PostCSS 插件函数`)
|
|
120
117
|
}
|
|
118
|
+
} catch (err) {
|
|
119
|
+
console.error(`加载 PostCSS 插件 ${key} 失败:`, err)
|
|
120
|
+
}
|
|
121
121
|
}
|
|
122
|
+
} else {
|
|
123
|
+
plugins.push(...cfg.plugins)
|
|
124
|
+
}
|
|
122
125
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
126
|
+
} catch (err) {
|
|
127
|
+
console.error('加载 PostCSS 配置失败:', err)
|
|
128
|
+
}
|
|
129
|
+
config[typing] = plugins
|
|
130
|
+
return {
|
|
131
|
+
plugins: config[typing]
|
|
132
|
+
}
|
|
133
|
+
}
|
|
131
134
|
/**
|
|
132
135
|
*
|
|
133
136
|
* @param inputPath
|
|
@@ -135,68 +138,63 @@ const loadPostcssConfig = (configPath, typing) => {
|
|
|
135
138
|
* @returns
|
|
136
139
|
*/
|
|
137
140
|
const postCSS = (inputPath, outputPath) => {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
141
|
+
const configPath = join(process.cwd(), 'postcss.config.cjs')
|
|
142
|
+
let typing = 'css'
|
|
143
|
+
let parser = undefined
|
|
144
|
+
if (/\.sass$/.test(inputPath)) {
|
|
145
|
+
typing = 'sass'
|
|
146
|
+
} else if (/\.less$/.test(inputPath)) {
|
|
147
|
+
typing = 'less'
|
|
148
|
+
} else if (/\.scss$/.test(inputPath)) {
|
|
149
|
+
typing = 'scss'
|
|
150
|
+
}
|
|
151
|
+
const postcssConfig = loadPostcssConfig(configPath, 'css')
|
|
152
|
+
if (!postcssConfig) return
|
|
153
|
+
const readAndProcessCSS = async () => {
|
|
154
|
+
let css = ''
|
|
155
|
+
if (typing === 'less') {
|
|
156
|
+
const less = require('less')
|
|
157
|
+
const lessResult = await less.render(fs.readFileSync(inputPath, 'utf-8'), {
|
|
158
|
+
filename: inputPath,
|
|
159
|
+
plugins: [LessAliasPlugin(createAlias(global.lvyConfig?.alias))] // 使用插件
|
|
160
|
+
})
|
|
161
|
+
css = lessResult.css
|
|
162
|
+
} else if (typing === 'sass' || typing === 'scss') {
|
|
163
|
+
const sass = require('sass')
|
|
164
|
+
const sassResult = sass.renderSync({ file: inputPath })
|
|
165
|
+
css = sassResult.css.toString()
|
|
166
|
+
} else {
|
|
167
|
+
css = fs.readFileSync(inputPath, 'utf-8')
|
|
143
168
|
}
|
|
144
|
-
|
|
145
|
-
|
|
169
|
+
fs.mkdirSync(dirname(outputPath), { recursive: true })
|
|
170
|
+
const result = await postcss(postcssConfig.plugins).process(css, {
|
|
171
|
+
parser: parser,
|
|
172
|
+
from: inputPath,
|
|
173
|
+
to: outputPath
|
|
174
|
+
})
|
|
175
|
+
fs.writeFileSync(outputPath, result.css)
|
|
176
|
+
if (result.warnings().length) {
|
|
177
|
+
result.warnings().forEach(warn => {
|
|
178
|
+
console.warn(warn.toString())
|
|
179
|
+
})
|
|
146
180
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
return;
|
|
153
|
-
const readAndProcessCSS = async () => {
|
|
154
|
-
let css = '';
|
|
155
|
-
if (typing === 'less') {
|
|
156
|
-
const less = require('less');
|
|
157
|
-
const lessResult = await less.render(fs.readFileSync(inputPath, 'utf-8'), {
|
|
158
|
-
filename: inputPath,
|
|
159
|
-
plugins: [LessAliasPlugin(createAlias(global.lvyConfig?.alias))] // 使用插件
|
|
160
|
-
});
|
|
161
|
-
css = lessResult.css;
|
|
162
|
-
}
|
|
163
|
-
else if (typing === 'sass' || typing === 'scss') {
|
|
164
|
-
const sass = require('sass');
|
|
165
|
-
const sassResult = sass.renderSync({ file: inputPath });
|
|
166
|
-
css = sassResult.css.toString();
|
|
167
|
-
}
|
|
168
|
-
else {
|
|
169
|
-
css = fs.readFileSync(inputPath, 'utf-8');
|
|
170
|
-
}
|
|
171
|
-
fs.mkdirSync(dirname(outputPath), { recursive: true });
|
|
172
|
-
const result = await postcss(postcssConfig.plugins).process(css, {
|
|
173
|
-
parser: parser,
|
|
174
|
-
from: inputPath,
|
|
175
|
-
to: outputPath
|
|
176
|
-
});
|
|
177
|
-
fs.writeFileSync(outputPath, result.css);
|
|
178
|
-
if (result.warnings().length) {
|
|
179
|
-
result.warnings().forEach(warn => {
|
|
180
|
-
console.warn(warn.toString());
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
const dependencies = result.messages
|
|
184
|
-
.filter(msg => msg.type === 'dependency')
|
|
185
|
-
.map(msg => msg.file);
|
|
186
|
-
for (const dep of dependencies) {
|
|
187
|
-
fs.watch(dep, eventType => {
|
|
188
|
-
if (eventType === 'change') {
|
|
189
|
-
readAndProcessCSS();
|
|
190
|
-
}
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
};
|
|
194
|
-
readAndProcessCSS();
|
|
195
|
-
fs.watch(inputPath, eventType => {
|
|
181
|
+
const dependencies = result.messages
|
|
182
|
+
.filter(msg => msg.type === 'dependency')
|
|
183
|
+
.map(msg => msg.file)
|
|
184
|
+
for (const dep of dependencies) {
|
|
185
|
+
fs.watch(dep, eventType => {
|
|
196
186
|
if (eventType === 'change') {
|
|
197
|
-
|
|
187
|
+
readAndProcessCSS()
|
|
198
188
|
}
|
|
199
|
-
|
|
200
|
-
}
|
|
189
|
+
})
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
readAndProcessCSS()
|
|
193
|
+
fs.watch(inputPath, eventType => {
|
|
194
|
+
if (eventType === 'change') {
|
|
195
|
+
readAndProcessCSS()
|
|
196
|
+
}
|
|
197
|
+
})
|
|
198
|
+
}
|
|
201
199
|
|
|
202
|
-
export { LessAliasPlugin as default, postCSS }
|
|
200
|
+
export { LessAliasPlugin as default, postCSS }
|