javascript - 如何使用 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结构文件,正确的资产通过入口配置传递,但它不能正常工作。
- 第一:如果原始文件夹没有.js,它仍然会在相应的dist文件夹中生成一个。
- 第二:如果原始文件夹同时具有 .scss 和 .js 文件,它们将生成 .css 文件和 .js 文件,但是虽然第一个似乎可以正常工作,但 .js 将无法按预期工作。以创建moduleDemo.js的moduleDemo文件夹为例:
/******/ (() => { // 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
需要考虑的旁注
该项目实际上有两种配置:
- 一个是基本的,对应mainConfig——它需要一个组合的css和一个组合的js文件输出到dist文件夹中。这个配置工作得很好,除了它还生成了一个style.js文件,这不是必需的。这是src目录:
│ │ │ ├─ 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
- 第二个对应blockConfig,这个线程中解释的主要问题。
当前的 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];
该文件绝对不是很干净。有很多东西可以让它看起来更好、更高效,所以我当然也愿意接受建议。
无论如何,有没有办法实现我正在寻找的东西以及如何实现?
解决方案
推荐阅读
- python - 如何将两个列表合并到字典中并对重复键的值求和
- sql - 我们如何将两行的选定字段与字符进行比较
- json - 无法在 JSON 中指定复制循环
- angular - 在 IE11 中发布样式 Angular Material mat-menu
- excel - 如何选择一个文件名(变量)一次,并为每个后续执行使用相同的文件名,而无需选择文件
- web-crawler - 发生 Fetch_Error 时自动删除 Fetched 记录
- laravel - Laravel 发送或队列邮件取决于配置设置
- python - 如何在 Python 中只保留数据框中的特定行?
- html - 单击链接后可滚动的垂直菜单跳到顶部
- javascript - Aurelia 没有收到带有 fetch 客户端的 json 响应