首页 > 解决方案 > 如何使用 src 目录中的多个入口文件在 dist 目录中生成对应的文件?

问题描述

问题描述

使用Webpack,我正在尝试使用src目录中的多个入口文件在dist目录中生成对应的文件。

预期结果 :

│ │ │ ├─ dist
│ │ │ │ ├─ script.js
│ │ │ │ ├─ style.css
│ │ │ │ ├─ template-parts
│ │ │ │ │ ├─ blocks
│ │ │ │ │ │ ├─ moduleDemo
│ │ │ │ │ │ │ ├─ moduleDemo.css
│ │ │ │ │ │ ├─ moduleDemo2
│ │ │ │ │ │ │ ├─ moduleDemo2.css
│ │ │ │ │ │ │ ├─ moduleDemo2.js
│ │ │ │ │ │ ├─ moduleDemo3
│ │ │ │ │ │ │ ├─ moduleDemo3.js
│ │ │ │ │ ├─ component
│ │ │ │ │ │ ├─ componentTitle
│ │ │ │ │ │ │ ├─ componentTitle.css
│ │ │ │ │ │ │ ├─ componentTitle.js
│ │ │ │ │ │ └─ componentWysiwyg
│ │ │ │ │ │ ├─ componentWysiwyg.js
│ │ │ │ │ └─ patterns
│ │ │ │ │ ├─ demo-pattern-2.php
│ │ │ │ │ └─ demo-pattern.php
│ │ │ │ ├─ templates
│ │ │ │ │ ├─ 404.twig
│ │ │ │ │ ├─ archive.twig
│ │ │ │ │ ├─ etc ...
│ │ │ │ ├─ twig.css
│ │ │ │ ├─ twig.js
│ │ │ ├─ footer.php
│ │ │ ├─ functions.php
│ │ │ ├─ package-lock.json
│ │ │ ├─ package.json
│ │ │ ├─ etc ...
│ │ │ ├─ src
│ │ │ │ ├─ assets
│ │ │ │ ├─ js
│ │ │ │ │ ├─ app.js
│ │ │ │ │ └─ test.js
│ │ │ │ ├─ scss
│ │ │ │ │ ├─ abstracts
│ │ │ │ │ │ └─ \_variables.scss
│ │ │ │ │ ├─ base
│ │ │ │ │ │ └─ \_typography.scss
│ │ │ │ │ ├─ components
│ │ │ │ │ │ └─ \_button.scss
│ │ │ │ │ ├─ layout
│ │ │ │ │ │ └─ \_footer.scss
│ │ │ │ │ ├─ main.scss
│ │ │ │ │ ├─ pages
│ │ │ │ │ │ └─ \_404.scss
│ │ │ │ │ └─ themes
│ │ │ │ │ └─ \_theme.scss
│ │ │ │ ├─ template-parts
│ │ │ │ │ ├─ blocks
│ │ │ │ │ │ ├─ moduleDemo
│ │ │ │ │ │ │ ├─ moduleDemo.scss
│ │ │ │ │ │ ├─ moduleDemo2
│ │ │ │ │ │ │ ├─ moduleDemo2.scss
│ │ │ │ │ │ │ ├─ moduleDemo2.js
│ │ │ │ │ │ ├─ moduleDemo3
│ │ │ │ │ │ │ ├─ moduleDemo3.js
│ │ │ │ │ ├─ component
│ │ │ │ │ │ ├─ componentTitle
│ │ │ │ │ │ │ ├─ componentTitle.scss
│ │ │ │ │ │ │ ├─ componentTitle.js
│ │ │ │ │ │ └─ componentWysiwyg
│ │ │ │ │ │ ├─ componentWysiwyg.js
│ │ │ │ │ └─ patterns
│ │ │ │ │ ├─ demo-pattern-2.php
│ │ │ │ │ └─ demo-pattern.php
│ │ │ │ ├─ templates
│ │ │ │ │ ├─ 404.twig
│ │ │ │ │ ├─ archive.twig
│ │ │ │ │ ├─ etc ...
│ │ │ │ └─ twig.js
│ │ │ ├─ static
│ │ │ │ ├─ no-timber.html
│ │ │ │ └─ site.js
│ │ │ ├─ style.css
│ │ │ ├─ system
│ │ │ │ └─ inc
│ │ │ │ └─ utils.class.php
│ │ │ └─ webpack.config.js

现在,我正在使用glob插件和entryPlus插件来查找所有相关的文件夹和 scss + js 文件,然后返回到条目配置:

const entryFiles = [
    {
        entryFiles: glob.sync('./src/template-parts/**/**/*.{scss,js}'),
        outputName(item) {
            let regex = /(\.scss)|(\.js)|(\.\/src\/)/g;
            return item.replaceAll(regex, '');
        },
    },
];

console.log(entryFiles);

let blockConfig = Object.assign({}, config, {
    entry: entryPlus(entryFiles),

    output: {
        filename: '[name].js',
        chunkFilename: '[name].js?ver=[chunkhash]',
        path: path.resolve(__dirname, 'dist'),
    },

console.log显示以下条目:

[
  {
    entryFiles: [
      './src/template-parts/blocks/moduleDemo/moduleDemo.js',
      './src/template-parts/blocks/moduleDemo/moduleDemo.scss',
      './src/template-parts/blocks/moduleDemo2/moduleDemo2.scss',
      './src/template-parts/blocks/moduleDemo3/moduleDemo3.js',
      './src/template-parts/component/componentTitle/componentTitle.js',
      './src/template-parts/component/componentWysiwyg/componentWysiwyg.js'
    ],
    outputName: [Function: outputName]
  }
]

所以从技术上讲,基于src结构文件,正确的资产通过入口配置传递,但它不能正常工作。

/******/ (() => { // webpackBootstrap
/******/    "use strict";
/******/    // The require scope
/******/    var __webpack_require__ = {};
/******/    
/************************************************************************/
/******/    /* webpack/runtime/make namespace object */
/******/    (() => {
/******/        // define __esModule on exports
/******/        __webpack_require__.r = (exports) => {
/******/            if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/                Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/            }
/******/            Object.defineProperty(exports, '__esModule', { value: true });
/******/        };
/******/    })();
/******/    
/************************************************************************/
var __webpack_exports__ = {};
/*!**************************************************************!*\
  !*** ./src/template-parts/blocks/moduleDemo/moduleDemo.scss ***!
  \**************************************************************/
__webpack_require__.r(__webpack_exports__);
// extracted by mini-css-extract-plugin

/******/ })()
;
//# sourceMappingURL=moduleDemo.js.map

需要考虑的旁注

该项目实际上有两种配置:

│ │ │ ├─ src
│ │ │ │ ├─ assets
│ │ │ │ ├─ js
│ │ │ │ │ ├─ app.js
│ │ │ │ │ └─ test.js
│ │ │ │ ├─ scss
│ │ │ │ │ ├─ abstracts
│ │ │ │ │ │ ├─ \_functions.scss
│ │ │ │ │ │ ├─ \_mixins.scss
│ │ │ │ │ │ └─ \_variables.scss
│ │ │ │ │ ├─ base
│ │ │ │ │ │ └─ \_typography.scss
│ │ │ │ │ ├─ components
│ │ │ │ │ │ └─ \_button.scss
│ │ │ │ │ ├─ layout
│ │ │ │ │ │ ├─ \_footer.scss
│ │ │ │ │ │ └─ \_header.scss
│ │ │ │ │ ├─ main.scss
│ │ │ │ │ ├─ pages
│ │ │ │ │ │ └─ \_404.scss
│ │ │ │ │ └─ themes
│ │ │ │ │ ├─ \_admin.scss
│ │ │ │ │ └─ \_theme.scss

这是对应的dist文件夹(我自愿删除 .map 生成的文件以使其更具可读性):

│ │ │ ├─ dist
│ │ │ │ ├─ script.js
│ │ │ │ ├─ style.css
│ │ │ │ ├─ style.js

当前的 Webpack 配置

const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
// const WatchTimePlugin = require('webpack-watch-time-plugin');
const cssnano = require('cssnano');
const autoprefixer = require('autoprefixer');
// const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const entryPlus = require('webpack-entry-plus');
const glob = require('glob');

let config = {
    module: {},
    plugins: [
        new MiniCssExtractPlugin({
            filename: '[name].css',
            chunkFilename: '[id].css',
        }),
    ],
};

let mainConfig = Object.assign({}, config, {
    entry: {
        twig: './src/twig.js',
        style: './src/scss/main.scss',
        script: './src/js/app.js',
    },
    output: {
        filename: '[name].js',
        chunkFilename: '[name].js?ver=[chunkhash]',
        path: path.resolve(__dirname, 'dist'),
    },
    resolve: {
        extensions: ['*', '.js'],
    },
    mode: 'development',
    performance: {
        hints: false,
    },
    devtool: 'source-map',
    module: {
        rules: [
            {
                test: /\.twig$/,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            context: 'src',
                            name: '[path][name].[ext]',
                        },
                    },
                    { loader: 'extract-loader' },
                    {
                        loader: 'html-loader',
                        options: {
                            minimize: false,
                            sources: {
                                list: [
                                    {
                                        tag: 'img',
                                        attribute: 'data-srcset',
                                        type: 'srcset',
                                    },
                                ],
                            },
                        },
                    },
                ],
            },
            {
                test: /\.php$/,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            context: 'src',
                            name: '[path][name].[ext]',
                        },
                    },
                    { loader: 'extract-loader' },
                    {
                        loader: 'html-loader',
                        options: {
                            minimize: false,
                        },
                    },
                ],
            },
            {
                test: /\.json$/,
                type: 'javascript/auto',
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            context: 'src',
                            name: '[path][name].[ext]',
                        },
                    },
                    { loader: 'extract-loader' },
                    {
                        loader: 'html-loader',
                        options: {
                            minimize: false,
                        },
                    },
                ],
            },
            {
                test: /\.js$/,
                use: [
                    {
                        loader: 'babel-loader',
                        options: {
                            presets: ['@babel/env'],
                        },
                    },
                ],
            },
            {
                test: /\.(png|svg|jpg|jpeg|tiff|webp|gif|ico|woff|woff2|eot|ttf|otf|mp4|webm|wav|mp3|m4a|aac|oga)$/,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            context: 'src',
                            name: '[path][name].[ext]?ver=[md5:hash:8]',
                        },
                    },
                ],
            },
        ],
    },
});

const entryFiles = [
    {
        entryFiles: glob.sync('./src/template-parts/**/**/*.{scss,js}'),
        outputName(item) {
            let regex = /(\.scss)|(\.js)|(\.\/src\/)/g;
            return item.replaceAll(regex, '');
        },
    },
];

console.log(entryFiles);

let blockConfig = Object.assign({}, config, {
    entry: entryPlus(entryFiles),

    output: {
        filename: '[name].js',
        chunkFilename: '[name].js?ver=[chunkhash]',
        path: path.resolve(__dirname, 'dist'),
    },
    mode: 'development',
    performance: {
        hints: false,
    },
    devtool: 'source-map',
    module: {
        rules: [
            {
                test: /\.js$/,
                use: [
                    {
                        loader: 'babel-loader',
                        options: {
                            presets: ['@babel/env'],
                        },
                    },
                ],
            },
        ],
    },
});

mainConfig.module.rules.push({
    test: /\.s?css$/,
    use: [
        MiniCssExtractPlugin.loader,
        {
            loader: 'css-loader',
            options: {
                sourceMap: true,
            },
        },
        {
            loader: 'sass-loader',
            options: {
                sourceMap: true,
            },
        },
    ],
});

blockConfig.module.rules.push({
    test: /\.s?css$/,
    use: [
        MiniCssExtractPlugin.loader,
        {
            loader: 'css-loader',
            options: {
                sourceMap: true,
            },
        },
        {
            loader: 'sass-loader',
            options: {
                sourceMap: true,
            },
        },
    ],
});

module.exports = [mainConfig, blockConfig];

该文件绝对不是很干净。有很多东西可以让它看起来更好、更高效,所以我当然也愿意接受建议。

无论如何,有没有办法实现我正在寻找的东西以及如何实现?

标签: javascriptcsswebpacksass

解决方案


推荐阅读