webpack - "Module parse failed: Unexpected token" 在不链接 css-loader 的情况下使用 less-loader

webpack - "Module parse failed: Unexpected token" when using less-loader without chaining css-loader

我需要一些帮助来理解 webpack less-loader 的行为。

我正在使用 webpack 4.5.0。

这是我的 webpack 配置:

const fs = require('fs');
const path = require('path');

const config = {
    entry: './src/index.js',
    mode: 'development',
    output: {
        filename: 'webpack-bundle.js',
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                include: path.resolve(__dirname, 'src'),
                use: {
                    loader: 'babel-loader',
                    options: {
                        cacheDirectory: true,
                        presets: ['react'],
                    }
                }
            },
            {
                test: /\.css$/,
                use: 'css-loader',
            },
            {
                test: /\.less$/,
                use: 'less-loader',
            },
        ],
    },
};

module.exports = config;

这是我的源文件结构:

src
 |- index.html
 |- index.js
 |- index.css
 |- index.less
webpack.config.js
package.json

这里是package.json的内容:

{
    "name": "xxx",
    "version": "2.1.0",
    "private": true,
    "scripts": {
        "build": "$(yarn bin)/webpack"
    },
    "devDependencies": {
        "babel-core": "^6.26.0",
        "babel-loader": "^7.1.4",
        "babel-preset-react": "^6.24.1",
        "css-loader": "^0.28.11",
        "less": "^3.0.1",
        "less-loader": "^4.1.0",
        "react": "^16.3.2",
        "react-dom": "^16.3.2",
        "webpack": "^4.5.0",
        "webpack-cli": "^2.0.14"
    }
}

这里是index.less的内容:

body {
    background: #000;
}

当我 运行 yarn build 时,我得到这些输出:

$ yarn build
yarn run v1.5.1
$ $(yarn bin)/webpack
Hash: deadade0357a0f63a681
Version: webpack 4.5.0
Time: 690ms
Built at: 2018-4-18 17:18:37
            Asset     Size  Chunks             Chunk Names
webpack-bundle.js  695 KiB    main  [emitted]  main
Entrypoint main = webpack-bundle.js
[./src/index.css] 192 bytes {main} [built]
[./src/index.js] 339 bytes {main} [built]
[./src/index.less] 163 bytes {main} [built] [failed] [1 error]
    + 22 hidden modules

ERROR in ./src/index.less
Module parse failed: Unexpected token (1:5)
You may need an appropriate loader to handle this file type.
| body {
|   background: #000;
| }
 @ ./src/index.js 5:0-22

可以看到,js文件和css文件都被编译了,但是没有less文件。

我在这里错过了什么?为什么它告诉我缺少合适的加载程序?


更新:

为了验证@felixmosh 所说的,我稍微更新了index.less

body {
    a {
        text-decoration: none;
    }
}

再次编译时,报错信息变为:

...
[./src/index.less] 170 bytes {main} [built] [failed] [1 error]
    + 22 hidden modules

ERROR in ./src/index.less
Module parse failed: Unexpected token (1:5)
You may need an appropriate loader to handle this file type.
| body a {
|   text-decoration: none;
| }
 @ ./src/index.js 5:0-22

如您所见,更少的代码实际上被编译为 css(body a 部分)。

在 webpack.config.js 中将 less-loader 与 css-loader 链接后:

const path = require('path');

const config = {
    ...
    module: {
        rules: [
            ...
            {
                test: /\.less$/,
                use: [
                    {
                        loader: 'css-loader',
                    },
                    {
                        loader: 'less-loader',
                    },
                ],
            },
        ],
    },
};

module.exports = config;

构建输出更改为:

Built at: 2018-4-19 10:59:58
            Asset     Size  Chunks             Chunk Names
webpack-bundle.js  695 KiB    main  [emitted]  main
Entrypoint main = webpack-bundle.js
[./src/index.css] 192 bytes {main} [built]
[./src/index.js] 339 bytes {main} [built]
[./src/index.less] 198 bytes {main} [built]
    + 22 hidden modules
Done in 1.38s.

所有代码都已成功编译和捆绑。

一句话,less-loader只负责将less代码转换为css,不将css转换为js webpack 能够理解并包含在最终的 bundle js.

这就是为什么我们需要将 less-loader 与 css-loader 链接起来以正确捆绑 less。

less-loader 是一个将 less 转换为 css 的加载器,如果没有合适的加载器,webpack 无法理解 css

在这种情况下,您需要连接所有 css 相关的加载器。

{
  test: /\.less$/,
  use: ['css-loader', 'less-loader'],
},