less-loader

免责声明: less-loader 是由社区成员维护的第三方包,它可能不支持 webpack 的相同支持、安全策略或许可证,并且它不受 webpack 维护。

npm node tests cover discussion size

用于 webpack 的 Less 加载器。将 Less 编译为 CSS。

入门

首先,你需要安装 lessless-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

选项

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 选项。除了 evalfalse 值以外,所有值都启用源映射生成。

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;

默认值: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 和 4 版本

特殊的 implementation 选项决定使用哪个 Less 实现。覆盖本地安装的 lesspeerDependency 版本。

此选项实际上只对下游工具作者有用,以简化 Less 3 到 4 的过渡。

object

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.less$/i,
        use: [
          "style-loader",
          "css-loader",
          {
            loader: "less-loader",
            options: {
              implementation: require("less"),
            },
          },
        ],
      },
    ],
  },
};

string

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-loadercss-loaderstyle-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 不会将所有选项逐一映射到 camelCase。如有疑问,请查看其可执行文件并搜索短横线选项。

源映射

要为 CSS 启用源映射,你需要在加载器的选项中传递 sourceMap 属性。如果不传递此属性,加载器将遵循 webpack 源映射的设置,该设置在 devtool 中设置。

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 解析器

webpack 提供了一个 高级机制来解析文件。如果 less 无法解析 @importless-loader 会应用一个 Less 插件,将所有查询传递给 webpack 解析器。因此,你可以从 node_modules 导入 Less 模块。

@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"],
      },
    },
  },
};

Less 解析器

如果你指定 paths 选项,将在给定的 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")],
              },
            },
          },
        ],
      },
    ],
  },
};

插件

要使用插件,只需像这样设置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 引用图像和字体,或在开发中进行热模块替换。另一方面,在生产中,最好不要根据 JS 执行应用样式表。渲染可能会延迟,甚至可能会看到FOUC。因此,在最终的生产构建中将它们作为单独的文件通常仍然更好。

有两种方法可以从捆绑中提取样式表

CSS 模块问题

Less 和CSS 模块存在一个已知问题,涉及url(...)语句中的相对文件路径。参阅此问题以获取解释

贡献

如果您尚未这样做,请花点时间阅读我们的贡献指南。

贡献

许可证

MIT