如何使用Webpack 5生成压缩和未压缩的资产?

nwlqm0z1  于 2023-06-23  发布在  Webpack
关注(0)|答案(1)|浏览(131)

我需要为我的自定义Joomla 4模板生成缩小和未压缩的资产,所以我编写了下一个webpack.config.js

const path = require('path');

const CopyPlugin = require('copy-webpack-plugin');
const TerserPlugin = require("terser-webpack-plugin");

const dist_path = path.resolve(__dirname, 'dist');
const media_root_path = 'media/templates/site/tofu';

module.exports = {
  devtool: 'source-map',
  entry: {
    'js/template.js': './src/js/template.js',
    'css/template.css': './src/scss/template.scss',
    'js/template.min.js': './src/js/template.js',
    'css/template.min.css': './src/scss/template.scss',
  },
  output: {
    path: dist_path, 
    filename: "media/templates/site/tofu/[name]",
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: [],
      },
      {
        test: /\.scss$/,
        exclude: /node_modules/,
        type: 'asset/resource',
        generator: {
          filename: media_root_path + '/css/template.min.css',
        },
        use: [
          // Compiles Sass to CSS
          {
            loader: 'sass-loader',
            options: {
              sourceMap: true,
              // Prefer `dart-sass`
              implementation: require('sass'),
            },
          },
        ],
      },
    ],
  },
  plugins: [
    new CopyPlugin({
      patterns: [
        { from: path.resolve(__dirname, 'src/index.php'), to: path.resolve(dist_path, 'index.php') },
        { from: path.resolve(__dirname, 'src/joomla.asset.json'), to: path.resolve(dist_path, 'joomla.asset.json') },
        { from: path.resolve(__dirname, 'src/templateDetails.xml'), to: path.resolve(dist_path, 'templateDetails.xml') },
        { from: path.resolve(__dirname, 'src/images'), to: path.resolve(dist_path, media_root_path, 'images') },
      ],
    })
  ],
  optimization: {
    minimize: true,
    minimizer: [new TerserPlugin({
      include: /\.min\.js$/
    })],
  },
  stats: {
    loggingDebug: ['sass-loader']
  },
};

对于JavaScript部分,它工作得很理想。但是,我无法正确配置它以将SCSS转换为CSS并生成***.css**、. min.css**. css.map**。
在原始变体(如上所述)中,我得到错误:

[webpack-cli] Error: Conflict: Multiple chunks emit assets to the same filename media/templates/site/tofu/css/template.min.css (chunks 61 and 301)
    at /Users/denis/Projects/tofu/node_modules/webpack/lib/Compilation.js:4625:12
    at /Users/denis/Projects/tofu/node_modules/webpack/lib/Cache.js:93:5
    at Hook.eval [as callAsync] (eval at create (/Users/denis/Projects/tofu/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:6:1)
    at Cache.get (/Users/denis/Projects/tofu/node_modules/webpack/lib/Cache.js:75:18)
    at ItemCacheFacade.get (/Users/denis/Projects/tofu/node_modules/webpack/lib/CacheFacade.js:115:15)
    at /Users/denis/Projects/tofu/node_modules/webpack/lib/Compilation.js:4571:22
    at arrayEach (/Users/denis/Projects/tofu/node_modules/neo-async/async.js:2405:9)
    at Object.each (/Users/denis/Projects/tofu/node_modules/neo-async/async.js:2846:9)
    at /Users/denis/Projects/tofu/node_modules/webpack/lib/Compilation.js:4560:14
    at symbolIterator (/Users/denis/Projects/tofu/node_modules/neo-async/async.js:3482:9)

如果注解最后一个条目('css/template.min.css': './src/scss/template.scss',),Webpack将成功构建项目,文件将看起来像我需要的,但template.css将无效:

/******/ (() => { // webpackBootstrap
/******/    "use strict";
/******/    var __webpack_modules__ = ({

/***/ 797:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

module.exports = __webpack_require__.p + "media/templates/site/tofu/css/template.min.css";

/***/ })

/******/    });
/************************************************************************/
/******/    // The module cache
/******/    var __webpack_module_cache__ = {};
/******/    
/******/    // The require function
/******/    function __webpack_require__(moduleId) {
/******/        // Check if module is in cache
/******/        var cachedModule = __webpack_module_cache__[moduleId];
/******/        if (cachedModule !== undefined) {
/******/            return cachedModule.exports;
/******/        }
/******/        // Create a new module (and put it into the cache)
/******/        var module = __webpack_module_cache__[moduleId] = {
/******/            // no module.id needed
/******/            // no module.loaded needed
/******/            exports: {}
/******/        };
/******/    
/******/        // Execute the module function
/******/        __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/    
/******/        // Return the exports of the module
/******/        return module.exports;
/******/    }
/******/    
/************************************************************************/
/******/    /* webpack/runtime/global */
/******/    (() => {
/******/        __webpack_require__.g = (function() {
/******/            if (typeof globalThis === 'object') return globalThis;
/******/            try {
/******/                return this || new Function('return this')();
/******/            } catch (e) {
/******/                if (typeof window === 'object') return window;
/******/            }
/******/        })();
/******/    })();
/******/    
/******/    /* webpack/runtime/publicPath */
/******/    (() => {
/******/        var scriptUrl;
/******/        if (__webpack_require__.g.importScripts) scriptUrl = __webpack_require__.g.location + "";
/******/        var document = __webpack_require__.g.document;
/******/        if (!scriptUrl && document) {
/******/            if (document.currentScript)
/******/                scriptUrl = document.currentScript.src;
/******/            if (!scriptUrl) {
/******/                var scripts = document.getElementsByTagName("script");
/******/                if(scripts.length) {
/******/                    var i = scripts.length - 1;
/******/                    while (i > -1 && !scriptUrl) scriptUrl = scripts[i--].src;
/******/                }
/******/            }
/******/        }
/******/        // When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration
/******/        // or pass an empty string ("") and set the __webpack_public_path__ variable from your code to use your own logic.
/******/        if (!scriptUrl) throw new Error("Automatic publicPath is not supported in this browser");
/******/        scriptUrl = scriptUrl.replace(/#.*$/, "").replace(/\?.*$/, "").replace(/\/[^\/]+$/, "/");
/******/        __webpack_require__.p = scriptUrl + "../../../../../";
/******/    })();
/******/    
/************************************************************************/
/******/    
/******/    // startup
/******/    // Load entry module and return exports
/******/    // This entry module doesn't tell about it's top-level declarations so it can't be inlined
/******/    var __webpack_exports__ = __webpack_require__(797);
/******/    
/******/ })()
;
/*# sourceMappingURL=template.css.map*/

说实话我都不知道那是什么
我做错了什么?

fwzugrvs

fwzugrvs1#

此时此刻,我已经解决了我的问题:

webpack.config.js:

const path = require('path');

const CopyPlugin = require('copy-webpack-plugin');
const TerserPlugin = require("terser-webpack-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

const dist_path = path.resolve(__dirname, 'dist');
const media_root_path = 'media/templates/site/tofu';

module.exports = {
  // devtool: 'source-map',
  entry: {
    'js/template': './src/js/template.js',
    'js/template.min': './src/js/template.js',
    'css/template': './src/scss/template.scss',
    'css/template.min': './src/scss/template.scss',
  },
  output: {
    path: dist_path, 
    filename: "media/templates/site/tofu/[name].js",
  },
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        include: /\.min\.js$/
      }),
      new CssMinimizerPlugin({
        include: /\.min\.css$/
      })
    ],
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: [],
      },
      {
        test: /\.s[ac]ss$/i,
        use: [
          MiniCssExtractPlugin.loader,
          "css-loader",
          {
            loader: "sass-loader",
            options: {
              // Prefer `dart-sass`
              implementation: require("sass"),
              sassOptions: {
                outputStyle: 'expanded'
              }
            },
          },
        ],
      },
    ],
  },
  plugins: [
    new CopyPlugin({
      patterns: [
        { from: path.resolve(__dirname, 'src/index.php'), to: path.resolve(dist_path, 'index.php') },
        { from: path.resolve(__dirname, 'src/joomla.asset.json'), to: path.resolve(dist_path, 'joomla.asset.json') },
        { from: path.resolve(__dirname, 'src/templateDetails.xml'), to: path.resolve(dist_path, 'templateDetails.xml') },
        { from: path.resolve(__dirname, 'src/images'), to: path.resolve(dist_path, media_root_path, 'images') },
      ],
    }),
    new MiniCssExtractPlugin({
      filename: "media/templates/site/tofu/[name].css",
    })
  ],
  stats: {
    loggingDebug: ['sass-loader']
  },
};

可惜的是,这个方案在css文件夹中还生成了template.jstemplate.min.js存根,所以我在package.json中添加了rm命令:"build": "webpack && rm -rf dist/media/templates/site/tofu/css/template*.js"

相关问题