【问题标题】:How to configure webpack 4 to not bundle multiple scss entry points如何配置 webpack 4 不捆绑多个 scss 入口点
【发布时间】:2018-08-06 11:43:54
【问题描述】:

您好,我有一个 webpack 配置,它基于一个 glob 条目和一个主 typescript 文件采用多个 scss 文件。问题是它将 scss 文件捆绑在一个 css 文件中,而我希望它们基于条目是单独的。 Webpack 肯定会看到 glob 中的所有文件。

生成的文件是所有 3 个文件的捆绑包。 我花了好几个小时在谷歌上搜索并尝试配置它,这让我发疯:愤怒:

我能找到的所有内容都显示了如何在手动指定多个输出时配置它们。或者对于带有不受支持的插件的旧版本的 webpack。

这是我当前的配置:

import * as webpack from "webpack";
import * as path from "path";
import * as glob from "glob";
import * as MiniCssExtractPlugin from "mini-css-extract-plugin";

const config: webpack.Configuration = {
  mode: "development",
  entry: glob.sync(
    "./src/themes/**/scss/*.main.scss",
    "./src/ts/theme-pack.ts"
  ),
  module: {
    rules: [
      {
        test: /\.ts?$/,
        use: "ts-loader",
        exclude: /node_modules/
      },
      {
        test: /\.scss$/,
        use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"]
      }
    ]
  },
  resolve: {
    extensions: [".js", ".css", ".ts", ".scss"]
  },
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "./dist")
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: "[name].css",
      chunkFilename: "[name].css"
    })
  ]

  //   //Dev server
  //   devServer: {
  //     contentBase: __dirname,
  //     compress: true,
  //     port: 8080
  // }
};

export default config;

有人可以帮忙吗?这看起来应该很简单,但是……

编辑

这就是我要做的。唯一的问题是它会生成与 css 同名的 js 文件。而且我找不到将css放入./dist/css并将js放入./dist/js的方法

import * as webpack from "webpack";
import * as path from "path";
import * as glob from "glob";
import * as MiniCssExtractPlugin from "mini-css-extract-plugin";


let entries = {
  "theme-pack": "./src/ts/theme-pack.ts"
};

function getEntries() {
  const files = glob.sync("./src/themes/**/scss/*.main.scss");
  files.forEach(file => {
    entries[path.basename(file)] = file;
  });
  return entries;
}

function perName() {
  // this function will create Objects that can splitChunks
  // testing each file in its own location
  return glob
    .sync("./src/themes/**/scss/*.main.scss")
    .reduce((obj, filename) => {
      const niceName = path.basename(filename);
      obj[niceName] = {
        test: new RegExp(filename),
        name: niceName,
        chunks: "all",
        enforce: true
      };
      return obj;
    }, {});
}

const config: webpack.Configuration = {
  mode: "development",
  entry: getEntries(),
  output: {
    path: path.resolve(__dirname, "./dist"),
    filename: "[name].js"
  },
  module: {
    rules: [
      {
        test: /\.ts?$/,
        use: "ts-loader",
        exclude: /node_modules/
      },
      {
        test: /\.scss$/,
        use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"]
      }
    ]
  },
  resolve: {
    extensions: [".js", ".css", ".ts", ".scss"]
  },

  plugins: [
    new MiniCssExtractPlugin({
      filename: "[name].css",
    })
  ],
  optimization: {
    splitChunks: {
      cacheGroups: perName()
    }
  }

  //   //Dev server
  //   devServer: {
  //     contentBase: __dirname,
  //     compress: true,
  //     port: 8080
  // }
};

export default config;

【问题讨论】:

    标签: node.js webpack sass


    【解决方案1】:

    在我看来,这里有 2 个选项可以实现这一目标。

    1) 使用 splitChunks

    optimization: {
      splitChunks: {
        cacheGroups: {
          adminLteStyles: {
            name: 'admin-lte',
            test: /admin-lte\.main\.scss$/,
            chunks: 'all',
            enforce: true
          },
          coreUiStyles: {
            name: 'coreui',
            test: /coreui\.main\.scss$/,
            chunks: 'all',
            enforce: true
          },
          
          // ... more
          
        }
      }
    },
    

    但是正如您所看到的,这需要为您拥有的每个 css 文件编写一个正则表达式块...当然您可以创建一个处理该问题的函数...

    function perTheme() {
      // this function will create Objects that can splitChunks
      // testing if the file is located under a specific theme directory
      return glob.sync("./src/themes/*/")
        .reduce((obj, theme) => {
          const niceName = path.basename(theme)
          obj[niceName] = {
            test: new RegExp(theme + "(.*).main.scss"),
            name: niceName,
            chunks: 'all',
            enforce: true
          }
          return obj;
        }, {})
    }
    
    function perName() {
      // this function will create Objects that can splitChunks
      // testing each file in its own location
      return glob.sync("./src/themes/*/scss/*.main.scss")
        .reduce((obj, filename) => {
          const niceName = path.basename(filename)
          obj[niceName] = {
            test: new RegExp(filename),
            name: niceName,
            chunks: 'all',
            enforce: true
          }
          return obj;
        }, {})
    }
    
    // in your webpack config ...
    
    
    optimization: {
        splitChunks: {
          cacheGroups: perTheme()
          // this will create one css file per theme
          // admin-lte theme etc..
        }
    }
    
    // OR
    
    optimization: {
        splitChunks: {
          cacheGroups: perName()
          // this will create one css file per scss you have
        }
    }
    

    我知道这可能很难配置,但请记住,使用这种方法拆分块非常强大。有很多方法可以使用这种方法拆分文件。如果您觉得这太过分了,请检查第二个选项!

    2) 使用提取加载器

    module: {
      rules: [{
        test: /\.scss$/,
        use: [{
            loader: 'file-loader',
            options: {
              name: "[name]-dist.[ext]",
            },
          },
          'extract-loader',
          "css-loader",
          "sass-loader"
        ]
      }]
    }
    

    因此,您可以简单地使用上述配置,而不是使用MiniCssExtractPlugin。这样,每个scss 文件将被转换为css,每个导入都将被解析,然后使用extract-loader,您将获得原始的css 字符串格式。之后file-loader 将输出一个带有这个原始css 的文件。因此,您最终会将每个 scss 文件转换为每个 css 相等。但正如您所见,这种简单的方法比第一种方法提供的分割块的方法少得多!

    【讨论】:

    • 非常感谢!我正在尝试类似的东西,但无法让它工作。我不得不遍历 glob 并将其添加到条目中以使其工作。唯一的问题是它会生成一个与 css 同名的 js 文件。而且我无法将css和js导出到./dist/css./dist/js的子目录中。它似乎忽略了`tsconfig.json`中的compilerOptions.outDir 我已经用最新的配置编辑了我的帖子。
    猜你喜欢
    • 2018-11-22
    • 2020-01-10
    • 1970-01-01
    • 2019-01-31
    • 1970-01-01
    • 2018-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多