代码之家  ›  专栏  ›  技术社区  ›  Abdullah Seba

如何将Webpack4配置为不捆绑多个scss入口点

  •  0
  • Abdullah Seba  · 技术社区  · 7 年前

    嗨,我有一个webpack配置,它基于一个glob条目和一个主typescript文件获取多个scss文件。问题是它将scss文件捆绑在一个css文件中,而我希望它们根据条目是独立的。 Webpack肯定能看到来自glob的所有文件。 enter image description here

    生成的文件是3个文件的捆绑包。 我花了大量的时间在谷歌上搜索,试图配置它,这让我疯狂:愤怒:

    我所能找到的一切都显示了如何配置多个输出,同时手动指定它们。或者对于带有不支持的插件的旧版本的网页包。

    这是我当前的配置:

    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;
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Alex Michailidis    7 年前

    在我看来,实现这一目标有两种选择。

    1)使用分割块

    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文件编写一个regex块。。。当然你可以创建一个函数来处理。。。

    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 平等。但正如你所看到的,这个简单的方法比第一种方法提供的分割块的方法要少得多!