繁体   English   中英

使用 webpack 将主题提取到不同的 css 5

[英]Extracting themes to different css using webpack 5

我正在尝试提取不同的 scss 条目以分隔 css 捆绑文件

我的文件夹结构类似于:

  • 源代码
    • 主题
      • 红色.scss
      • 蓝色.scss
    • index.js

red.scss 和 blue.scss 正在导入其他(相同的).scss 文件

index.js 不导入 any.scss

我希望我的 output 是:

  • index.js 或 bundle.js
  • 蓝色.css
  • 红色.css

我使用 minicssextractplugin 来完成这项工作,但我得到的只是:

  • index.js
  • 蓝色.js
  • 红色.js

使用了很多教程,但大多数都与 webpack 兼容 4. 使用了优化、splitChunks、cacheGroups 等各种不同的入门案例

我的依赖是:

  "devDependencies": {
    "@babel/core": "^7.12.10",
    "@babel/plugin-proposal-object-rest-spread": "^7.12.1",
    "@babel/preset-env": "^7.12.11",
    "babel-loader": "^8.2.2",
    "babel-polyfill": "^6.26.0",
    "clean-webpack-plugin": "^3.0.0",
    "css-loader": "^5.0.1",
    "file-loader": "^6.2.0",
    "mini-css-extract-plugin": "^1.3.3",
    "node-sass": "^5.0.0",
    "sass-loader": "^10.1.0",
    "style-loader": "^2.0.0",
    "url-loader": "^4.1.1",
    "webpack": "^5.11.0",
    "webpack-cli": "^4.2.0"
  },

我无法在此处复制我的 webpack.config.js,出现格式错误 这里有一些部分:

  entry: {
            red: path.resolve(__dirname, 'src/themes/red/'),
            blue: path.resolve(__dirname, 'src/themes/blue/'),
        },
        //devtool: 'source-map',
        //entry: './src/index.js',
        //entry: ['./src/index.js', './src/css/index.scss'],
        //entry: {
        //    //default: './src/default.js',
        //    blue: './src/themes/blue',
        //    red: './src/themes/red'
        //},
        //entry: {
        //    //index: './src/index.js',
        //    //main: './src/index.js',
        //    //styles: ['./src/themes/red.scss', './src/themes/default.scss', './src/themes/blue.scss']

        //    default: ['./src/default.js', './src/themes/default.scss'],
        //    red: ['./src/red.js', './src/themes/red.scss'],
        //    blue: ['./src/blue.js', './src/themes/blue.scss'],
        //},
  output: {
            path: path.resolve(__dirname, 'wwwroot/dist'),
            filename: '[name].js'
            //sourceMapFilename: '[name].js.map'
          },

 optimization: {
            splitChunks: {
                cacheGroups: {
                    redStyles: {
                        name: 'styles_red',
                        test: (m, c, entry = 'red') =>
                            m.constructor.name === 'CssModule' &&
                            recursiveIssuer(m, c) === entry,
                        chunks: 'all',
                        enforce: true,
                    },
                    blueStyles: {
                        name: 'styles_blue',
                        test: (m, c, entry = 'blue') =>
                            m.constructor.name === 'CssModule' &&
                            recursiveIssuer(m, c) === entry,
                        chunks: 'all',
                        enforce: true,
                    },
                },
            },
        },
module: {
            rules: [

                {
                    test: /\.s[c|a]ss$/,
                    include: path.resolve(__dirname, 'src'),
                    use: [
                        devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
                        'css-loader',
                        'sass-loader',
                    ]
                },
                //{
                //    test: /\.js$/,
                //    include: path.resolve(__dirname, 'src'),
                //    loader: 'babel-loader',
                //    options: {
                //        presets: ["@babel/preset-env"],
                //        plugins: ['@babel/plugin-proposal-object-rest-spread']
                //    }
                //},
                {
                    test: /\.(png|jpg)$/,
                    include: path.resolve(__dirname, 'src'),
                    use: {
                        loader: "file-loader"
                    }
                }
            ]
        }
 plugins: [
            new webpack.ProvidePlugin({
                $: 'jquery',
                jQuery: 'jquery'
            }),
            //new FixStyleOnlyEntriesPlugin(),
            new MiniCssExtractPlugin({
                filename: "[name].css",
            }),
            //new MiniCssExtractPlugin({
            //    filename: "[name].css",
            //    //chunkFilename: "[name].css"
            //})
            //new MiniCssExtractPlugin({
            //    filename: '[name].css'
            //}),
            //defaultTheme,
            //redTheme,
            //blueTheme
        ]

(我的答案副本)

我的案例:webpack 5 + 多页应用程序 + 主题。css 通过入口点

解决方案: https://github.com/webdiscus/webpack-remove-empty-scripts

此插件不适用于 webpack 5 入口点或 MiniCssExtractPlugin:

webpack-fix-style-only-entrieswebpack-extraneous-file-cleanup-pluginwebpack-remove-empty-js-chunks-pluginwebpack-delete-no-js-entries-plugin

我的webpack.config.js

const fs = require('fs');
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const RemoveEmptyScriptsPlugin = require('webpack-remove-empty-scripts');

const isProd = process.env.NODE_ENV === 'production';
const isDev = !isProd;

const PAGES = ['app', 'help'];

const getThemes = (themePath, alias) => {
  let themes = {};
  const longPath = './' + alias + '/' + themePath;
  fs.readdirSync(longPath).forEach(function(fileName) {
    const fileNameWithPath = path.join(themePath, fileName);
    const fileNameWithLongPath = path.join(longPath, fileName);

    const stat = fs.lstatSync(fileNameWithLongPath);
    if (stat.isDirectory()) return;
    if (!/\.scss$/.test(fileName)) return;

    const nameWithoutExt = path.basename(fileName, '.scss');
    themes[nameWithoutExt] = ['./' + fileNameWithPath];
  });
  console.log(themes);
  return themes;
};

const themes = getThemes('scss/themes', 'src');

const getFilename = (filename, ext) => {
  let name = filename == 'index' ? 'bundle' : filename;
  const isTheme = (ext == 'css' && name.startsWith('theme')) ? true : false;
  const needHash = (isDev || isTheme) ? false : true;
  return needHash ? name +`.[fullhash].` + ext : name+'.'+ext;
};

const getCSSDirname = filename => {
  const isTheme = filename.startsWith('theme');
  return !isTheme? '/css/' : '/css/theme/';
};

const getHTMLWebpackPlugins = arr => {
  // this function config multipages names and add to html-pages
  // inside <head> tag our themes via tag <link rel="stylesheet" href="....css" ...>
  // and return array of HTMLWebpackPlugins
};

module.exports = {
// ... //
  entry: {
    // mutipage:
    app:  ['./index.js', './scss/app.scss'], 
    help: ['./help.js', './scss/help.scss'],
    // multitheme:
    ...themes,
  },
  optimization: {
    removeEmptyChunks: true, // not work!!!
  },
  // ... //
  plugins: [
    // ... //
    ...getHTMLWebpackPlugins(PAGES),
    new RemoveEmptyScriptsPlugin({
      ignore:  PAGES,
      enabled: isDev === false,
    }),
    new MiniCssExtractPlugin({
      filename: pathdata => {
        return getCSSDirname(pathdata.chunk.name) + getFilename(pathdata.chunk.name, 'css');
      },
      chunkFilename: isDev ? '[id].css' : '[id].[contenthash].css',
    }),
  ],
};

我的源文件:

[src]:
 - index.js
 - index.html
 - help.js
 - help.html
 - [scss]:
 - - app.scss
 - - help.scss
 - - [themes]:
 - - - light.scss
 - - - dark.scss
 - - - blue.scss

构建后:

[dist]:
 - app.js
 - index.html
 - help$hash.js
 - help$hash.html
 - [css]:
 - - app$hash.css
 - - help$.css
 - - [themes]:
 - - - light.css
 - - - dark.css
 - - - blue.css

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM