ng-zorro-antd之less编译过程


源码分析如下
ts/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
import * as fs from 'fs-extra';
import * as less from 'less';
import * as path from 'path';
import { buildConfig } from '../build-config';
const lessPluginCleanCSS = require('less-plugin-clean-css');
const npmImportPlugin = require('less-plugin-npm-import');
async function compileLess(
content: string, // @root-entry-name: default;\n 再加上entry.less里的内容 @import './index.less';@import './patch.less';
savePath: string, //编译后的css保存路径 publish/组件名称/style/index.css
min: boolean, //是否对css压缩
sub?: boolean,
rootPath?: string //less路径 components/组件/style/entry.less
): Promise<void> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const plugins: any[] = [];
const lessOptions: Less.Options = { plugins, javascriptEnabled: true };
if (min) {
plugins.push(new lessPluginCleanCSS({ advanced: true }));
}
if (sub) {
// 待编译less路径 [components/affix/style]
lessOptions.paths = [path.dirname(rootPath as string)];
// 待编译less 文件名称 components/affix/style/entry.less
lessOptions.filename = rootPath;
plugins.push(
new npmImportPlugin({
prefix: '~'
})
);
}
// 编译less
return less
.render(content, lessOptions)
.then(({ css }) => {
return fs.writeFile(savePath, css); //将编译后的css写入到指定文件 publish/组件名称/style/index.css
})
.catch(err => Promise.reject(err));
}
const sourcePath = buildConfig.componentsDir;
const targetPath = buildConfig.publishDir;
export async function compile(): Promise<void | void[]> {
const componentFolders = fs.readdirSync(targetPath);
const promiseList = [];
console.log('componentFolders: ', componentFolders); // componsnts路径下所以的文件夹 组件
console.log('sourcePath: ', sourcePath); // /components
console.log('targetPath: ', targetPath); // /publish
for (const dir of componentFolders) {
// 每一个组件包下面有样式的才编译less
if (await fs.pathExists(`${sourcePath}/${dir}/style/index.less`)) {
// 将/components/组件/style样式文件 拷贝到/publish/组件/style
await fs.copy(`${sourcePath}/${dir}/style`, `${targetPath}/${dir}/style`);
// Compile less files to CSS and delete the `entry.less` file.
const buildFilePath = `${sourcePath}/${dir}/style/entry.less`;
const componentLess = await fs.readFile(buildFilePath, { encoding: 'utf8' });
if (await fs.pathExists(buildFilePath)) {
// Rewrite `entry.less` file with `root-entry-name`
const entryLessFileContent = needTransformStyle(componentLess)
? `@root-entry-name: default;\n${componentLess}`
: componentLess;
// entry.less里的内容
// @root-entry-name: default;
// @import './index.less';
// @import "./patch";
console.log('entryLessFileContent: ', entryLessFileContent);
// 编译未压缩版index.css
promiseList.push(
compileLess(
entryLessFileContent,
path.join(targetPath, dir, 'style', `index.css`),
false,
true,
buildFilePath
)
);
// 编译压缩版index.min.css
promiseList.push(
compileLess(
entryLessFileContent,
path.join(targetPath, dir, 'style', `index.min.css`),
true,
true,
buildFilePath
)
);
}
}
}
console.log('拷贝样式');
// 拷贝全局样式 把/components/style下的全局样式 拷贝到 /publish/style下面
await fs.copy(path.resolve(sourcePath, 'style'), path.resolve(targetPath, 'style'));
await fs.writeFile(`${targetPath}/components.less`, await fs.readFile(`${sourcePath}/components.less`));
await fs.writeFile(`${targetPath}/ng-zorro-antd.less`, await fs.readFile(`${sourcePath}/ng-zorro-antd.less`));
await fs.writeFile(
`${targetPath}/ng-zorro-antd.dark.less`,
await fs.readFile(`${sourcePath}/ng-zorro-antd.dark.less`)
);
await fs.writeFile(
`${targetPath}/ng-zorro-antd.aliyun.less`,
await fs.readFile(`${sourcePath}/ng-zorro-antd.aliyun.less`)
);
await fs.writeFile(
`${targetPath}/ng-zorro-antd.compact.less`,
await fs.readFile(`${sourcePath}/ng-zorro-antd.compact.less`)
);
await fs.writeFile(
`${targetPath}/ng-zorro-antd.variable.less`,
await fs.readFile(`${sourcePath}/ng-zorro-antd.variable.less`)
);
// 编译ng-zorro-antd.less
const lessContent = `@import "${path.posix.join(targetPath, 'ng-zorro-antd.less')}";`;
console.log(lessContent); //@import "磁盘路径/publish/ng-zorro-antd.less";
promiseList.push(compileLess(lessContent, path.join(targetPath, 'ng-zorro-antd.css'), false));
promiseList.push(compileLess(lessContent, path.join(targetPath, 'ng-zorro-antd.min.css'), true));
// 编译 ng-zorro-antd.dark.less
const darkLessContent = `@import "${path.posix.join(targetPath, 'ng-zorro-antd.dark.less')}";`;
promiseList.push(compileLess(darkLessContent, path.join(targetPath, 'ng-zorro-antd.dark.css'), false));
promiseList.push(compileLess(darkLessContent, path.join(targetPath, 'ng-zorro-antd.dark.min.css'), true));
// 编译 ng-zorro-antd.compact.less
const compactLessContent = `@import "${path.posix.join(targetPath, 'ng-zorro-antd.compact.less')}";`;
promiseList.push(compileLess(compactLessContent, path.join(targetPath, 'ng-zorro-antd.compact.css'), false));
promiseList.push(compileLess(compactLessContent, path.join(targetPath, 'ng-zorro-antd.compact.min.css'), true));
// 编译 ng-zorro-antd.aliyun.less
const aliyunLessContent = `@import "${path.posix.join(targetPath, 'ng-zorro-antd.aliyun.less')}";`;
promiseList.push(compileLess(aliyunLessContent, path.join(targetPath, 'ng-zorro-antd.aliyun.css'), false));
promiseList.push(compileLess(aliyunLessContent, path.join(targetPath, 'ng-zorro-antd.aliyun.min.css'), true));
// 编译 ng-zorro-antd.variable.less
const variableLessContent = `@import "${path.posix.join(targetPath, 'ng-zorro-antd.variable.less')}";`;
promiseList.push(compileLess(variableLessContent, path.join(targetPath, 'ng-zorro-antd.variable.css'), false));
promiseList.push(compileLess(variableLessContent, path.join(targetPath, 'ng-zorro-antd.variable.min.css'), true));
// Compile css file that doesn't have component-specific styles.
const cssIndexPath = path.join(sourcePath, 'style', 'entry.less');
console.log(cssIndexPath); // /磁盘全路径/ng-zorro-antd/components/style/entry.less
const cssIndex = await fs.readFile(cssIndexPath, { encoding: 'utf8' });
// Rewrite `entry.less` file with `root-entry-name`
const entryLessInStyle = needTransformStyle(cssIndex) ? `@root-entry-name: default;\n${cssIndex}` : cssIndex;
console.log(entryLessInStyle); // @root-entry-name: default;
// 编译全局style样式
promiseList.push(
compileLess(entryLessInStyle, path.join(targetPath, 'style', 'index.css'), false, true, cssIndexPath)
);
promiseList.push(
compileLess(entryLessInStyle, path.join(targetPath, 'style', 'index.min.css'), true, true, cssIndexPath)
);
return Promise.all(promiseList).catch(e => console.log(e));
}
function needTransformStyle(content: string): boolean {
return (
content.includes('../../style/index.less') || content.includes('./index.less') || content.includes('/entry.less')
);
}


本文作者:繁星
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!