webpack 的 Less 加载器,用于将 Less 文件编译为 CSS。
首先,你需要安装 less
和 less-loader
npm install less less-loader --save-dev
或
yarn add -D less less-loader
或
pnpm add -D less less-loader
然后将加载器添加到你的 webpack
配置中。例如:
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.less$/i,
use: [
// compiles Less to CSS
"style-loader",
"css-loader",
"less-loader",
],
},
],
},
};
最后,使用你通常使用的方法运行 webpack
(例如,通过 CLI 或 npm 脚本)。
lessOptions
类型
type lessOptions = import('less').options | ((loaderContext: LoaderContext) => import('less').options})
默认值: { relativeUrls: true }
你可以通过加载器选项中的 lessOptions
属性,向 less-loader
传递任何 Less 特定的选项。有关所有可用(以连字符分隔命名)的选项,请参阅 Less 文档。
由于我们是以编程方式将这些选项传递给 Less,因此你需要在此处使用驼峰命名法。
object
使用一个对象直接将选项传递给 Less。
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.less$/i,
use: [
{
loader: "style-loader",
},
{
loader: "css-loader",
},
{
loader: "less-loader",
options: {
lessOptions: {
strictMath: true,
},
},
},
],
},
],
},
};
function
允许根据加载器上下文动态设置 Less 选项。
module.exports = {
module: {
rules: [
{
test: /\.less$/i,
use: [
"style-loader",
"css-loader",
{
loader: "less-loader",
options: {
lessOptions: (loaderContext) => {
// More information about available properties https://webpack.js.cn/api/loaders/
const { resourcePath, rootContext } = loaderContext;
const relativePath = path.relative(rootContext, resourcePath);
if (relativePath === "styles/foo.less") {
return {
paths: ["absolute/path/c", "absolute/path/d"],
};
}
return {
paths: ["absolute/path/a", "absolute/path/b"],
};
},
},
},
],
},
],
},
};
additionalData
类型
type additionalData =
| string
| ((content: string, loaderContext: LoaderContext) => string);
默认值:undefined
在实际入口文件前或后附加 Less 代码。在这种情况下,less-loader
不会覆盖源文件,而只是在入口内容前 附加。
当你的某些 Less 变量依赖于环境时,这尤其有用。
由于你正在注入代码,这会破坏你入口文件中的源映射。通常有比这更简单的解决方案,例如多个 Less 入口文件。
string
module.exports = {
module: {
rules: [
{
test: /\.less$/i,
use: [
"style-loader",
"css-loader",
{
loader: "less-loader",
options: {
additionalData: `@env: ${process.env.NODE_ENV};`,
},
},
],
},
],
},
};
function
Sync
module.exports = {
module: {
rules: [
{
test: /\.less$/i,
use: [
"style-loader",
"css-loader",
{
loader: "less-loader",
options: {
additionalData: (content, loaderContext) => {
// More information about available properties https://webpack.js.cn/api/loaders/
const { resourcePath, rootContext } = loaderContext;
const relativePath = path.relative(rootContext, resourcePath);
if (relativePath === "styles/foo.less") {
return "@value: 100px;" + content;
}
return "@value: 200px;" + content;
},
},
},
],
},
],
},
};
Async
module.exports = {
module: {
rules: [
{
test: /\.less$/i,
use: [
"style-loader",
"css-loader",
{
loader: "less-loader",
options: {
additionalData: async (content, loaderContext) => {
// More information about available properties https://webpack.js.cn/api/loaders/
const { resourcePath, rootContext } = loaderContext;
const relativePath = path.relative(rootContext, resourcePath);
if (relativePath === "styles/foo.less") {
return "@value: 100px;" + content;
}
return "@value: 200px;" + content;
},
},
},
],
},
],
},
};
sourceMap
类型
type sourceMap = boolean;
默认值:取决于 compiler.devtool
的值
默认情况下,源映射的生成取决于 devtool
选项。除了 eval
和 false
值之外,所有值都启用源映射生成。
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.less$/i,
use: [
"style-loader",
{
loader: "css-loader",
options: {
sourceMap: true,
},
},
{
loader: "less-loader",
options: {
sourceMap: true,
},
},
],
},
],
},
};
webpackImporter
类型
type webpackImporter = boolean | "only";
默认值:true
启用或禁用默认的 webpack
导入器。
这在某些情况下可以提高性能。请谨慎使用,因为别名和从 node_modules
导入的 @import
将不起作用。
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.less$/i,
use: [
"style-loader",
"css-loader",
{
loader: "less-loader",
options: {
webpackImporter: false,
},
},
],
},
],
},
};
implementation
类型
type implementation = object | string;
less-loader 兼容 Less 3 和 Less 4 版本
特殊的 implementation
选项决定使用哪个 Less 实现。它会覆盖本地安装的 Less peerDependency
版本。
此选项仅对下游工具作者有用,可简化 Less 3 到 4 的过渡。
object
使用 Less 实例的示例
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.less$/i,
use: [
"style-loader",
"css-loader",
{
loader: "less-loader",
options: {
implementation: require("less"),
},
},
],
},
],
},
};
string
使用已解析的 Less 模块路径的示例
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.less$/i,
use: [
"style-loader",
"css-loader",
{
loader: "less-loader",
options: {
implementation: require.resolve("less"),
},
},
],
},
],
},
};
lessLogAsWarnOrErr
类型
type lessLogAsWarnOrErr = boolean;
默认值:false
Less 警告和错误将被视为 webpack 警告和错误,而不是静默记录。
warning.less
div {
&:extend(.body1);
}
如果 lessLogAsWarnOrErr
设置为 false
,它将只是一条日志,webpack 将成功编译;但如果将此选项设置为 true
,webpack 将因警告(或错误)而编译失败,并且如果配置得当,可能会中断构建。
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.less$/i,
use: [
"style-loader",
"css-loader",
{
loader: "less-loader",
options: {
lessLogAsWarnOrErr: true,
},
},
],
},
],
},
};
将 less-loader
与 css-loader
和 style-loader
链式调用,以立即将所有样式应用于 DOM。
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.less$/i,
use: [
{
loader: "style-loader", // Creates style nodes from JS strings
},
{
loader: "css-loader", // Translates CSS into CommonJS
},
{
loader: "less-loader", // Compiles Less to CSS
},
],
},
],
},
};
遗憾的是,Less 并非所有选项都一对一地映射到驼峰命名法。如有疑问,请检查其可执行文件并搜索连字符分隔的选项。
要为 CSS 启用源映射,您需要在加载器选项中传递 sourceMap
属性。如果未传递此属性,加载器将遵循 devtool
中设置的 webpack 源映射设置。
webpack.config.js
module.exports = {
devtool: "source-map", // any "source-map"-like devtool is possible
module: {
rules: [
{
test: /\.less$/i,
use: [
"style-loader",
{
loader: "css-loader",
options: {
sourceMap: true,
},
},
{
loader: "less-loader",
options: {
sourceMap: true,
},
},
],
},
],
},
};
如果你想在 Chrome 中编辑原始 Less 文件,有一篇不错的博客文章。这篇博客文章是关于 Sass 的,但它也适用于 Less。
通常,建议在生产环境中使用 MiniCssExtractPlugin 将样式表提取到专用文件中。这样,你的样式就不依赖于 JavaScript,从而提高了性能和可缓存性。
我们首先尝试使用 Less 内置的解析逻辑,然后是 webpack 的解析逻辑。
webpack
提供了一种高级的文件解析机制。如果 Less 无法解析 @import
,less-loader
会应用一个 Less 插件,将所有查询传递给 webpack 解析器。因此,你可以从 node_modules
导入 Less 模块。
@import "bootstrap/less/bootstrap";
使用 ~
前缀(例如,@import "~bootstrap/less/bootstrap";)已弃用,并且可以从你的代码中删除(我们推荐这样做),但出于历史原因我们仍支持它。为什么可以删除它?加载器会首先尝试将 @import
解析为相对路径,如果无法解析,加载器将尝试在 node_modules
中解析 @import
。
默认解析器选项可以通过 resolve.byDependency
进行修改。
webpack.config.js
module.exports = {
devtool: "source-map", // any "source-map"-like devtool is possible
module: {
rules: [
{
test: /\.less$/i,
use: ["style-loader", "css-loader", "less-loader"],
},
],
},
resolve: {
byDependency: {
// More options can be found here https://webpack.js.cn/configuration/resolve/
less: {
mainFiles: ["custom"],
},
},
},
};
如果你指定 paths
选项,模块将在给定路径中搜索。这是 Less 的默认行为。paths
应该是一个包含绝对路径的数组。
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.less$/i,
use: [
{
loader: "style-loader",
},
{
loader: "css-loader",
},
{
loader: "less-loader",
options: {
lessOptions: {
paths: [path.resolve(__dirname, "node_modules")],
},
},
},
],
},
],
},
};
为了使用Less 插件,只需像这样设置 plugins
选项即可:
webpack.config.js
const CleanCSSPlugin = require('less-plugin-clean-css');
module.exports = {
...
{
loader: 'less-loader',
options: {
lessOptions: {
plugins: [
new CleanCSSPlugin({ advanced: true }),
],
},
},
},
...
};
[!注意]
在自定义插件中访问加载器上下文可以通过
pluginManager.webpackLoaderContext
属性完成。
module.exports = {
install: function (less, pluginManager, functions) {
functions.add("pi", function () {
// Loader context is available in `pluginManager.webpackLoaderContext`
return Math.PI;
});
},
};
使用 webpack 打包 CSS 具有一些优势,例如在开发环境中引用带有哈希 URL 的图像和字体,或实现热模块替换(HMR)。
另一方面,在生产环境中,依赖 JS 执行来应用样式表不是一个好主意。渲染可能会延迟,甚至可能出现无样式内容闪烁(FOUC)的情况。因此,在最终的生产构建中将它们作为单独的文件通常仍然更好。
有两种方法可以从捆绑包中提取样式表
extract-loader
(更简单,但专门用于 css-loader 的输出)MiniCssExtractPlugin
(更复杂,但适用于所有用例)在使用 Less 和 CSS 模块时,关于 url(...)
语句中的相对文件路径存在一个已知问题。请参阅此问题以获取解释。
我们欢迎所有贡献!如果您是新用户,请在提交问题或拉取请求之前花一些时间阅读我们的贡献指南。