在webpack.config.js中使用Promise的结果

时间:2019-07-15 20:19:42

标签: javascript webpack es6-promise

我正在尝试在 webpack.config.js中访问在 recursive.js 中创建的Promise(文件路径数组)(遍历目录并对样式表进行排序) ,这样我就可以按照特定顺序编译所有样式表。

似乎 webpack.config.js 无法从 recursive.js 访问结果,并且无法生成我的.css / .scss文件包!

我实际上想不出一种解决方法...我认为在 .then(result => {中包含 module.exports = {...} ...})就足够了...但是我相信module.exports会在结果尚未准备好之前就尝试使用它,并且它只会生成 main.js

recursive.js

const readdirp = require('readdirp');

let files = readdirp.promise('src/lib/bs4',
    {
        entryType: 'files', fileFilter: ['*.css', '*.scss'], directoryFilter: ['!modulos', '!node_modules', '!assets']
    })
    .then(function (files) {
        return new Promise((resolve, reject) => {
            resolve(promises = files.map(files => files.path))
        })
    }).then(function (result) {
        let cssArr = []
        let scssArr = []
        result.forEach(e => {
            let temp = e.split('.')
            if (temp[temp.length - 1] === 'css') {
                cssArr.push(e)
                //cssArr.push(e.replace(/\\/g, '/'))
            } else {
                scssArr.push(e)
                //scssArr.push(e.replace(/\\/g, '/'))
            }
        })
        console.log(cssArr.concat(scssArr))
        return cssArr.concat(scssArr)
    })

exports.files = files

webpack.config.js

const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const ext = require('./recursive')


ext.files.then((result) => {
  return new Promise((resolve, reject) => {
    resolve(promises = result.map(e => e = path.resolve(__dirname, `src/lib/bs4/${e}`)))
    // .map(e => e.replace(/\\/g, '/')))
  })
})
  .then((result) => {
    console.log(result) // prints out the expected array of file paths!

    module.exports = {
      entry: {
        bundle: result,
        main: [
          path.resolve(__dirname, 'src/principal')
        ]
      },
      output: {
        filename: '[name].js',
        path: path.resolve(__dirname, 'dist'),
      },
      module: {
        rules: [
          {
            test: /\.(sa|sc|c)ss$/,
            use: [
              MiniCssExtractPlugin.loader,
              'css-loader',
              'sass-loader'
            ]
          },
        ],
      },
      plugins: [
        new MiniCssExtractPlugin({
          filename: "[name].css"
        }),
      ]
    };

  })

我相信我不应该在内的 webpack.config.js 文件中使用 module.exports 。then((result)=> {} )

还有其他解决方法吗?

谢谢,伙计们!

更新

我阅读了更多内容,以尝试了解FZ和Steve Holgado(非常感谢!)试图解释的内容,并且我修改了代码以使其表现为:

const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const readdirp = require('readdirp');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');

// extracts argument (path) from script command
const args = require('minimist')(process.argv.slice(2));

// development or production?
const devMode = process.env.NODE_ENV !== "production";

const configPromise = readdirp.promise('src/lib/bs4',
  {
    // if a file (stylesheets/images) is not being imported/required its extension needs to be added to the fileFilter: []
    // e.g.: removing '*.png' won't bundle images from 'src\lib\bs4\imgs'
    entryType: 'files', fileFilter: ['*.css', '*.scss', '*.png'], directoryFilter: ['!modulos', '!node_modules', '!assets']
  })
  .then(function (files) {
    return files = files.map(file => file.path);
  })
  .then(function (result) {
    return new Promise((resolve, reject) => {
      let cssArr = [];
      let scssArr = [];
      result.forEach(element => {
        let temp = element.split('.');

        (temp[temp.length - 1] === 'css') ? cssArr.push(element) : scssArr.push(element)

      })

      // .scss files first then .css
      result = scssArr.concat(cssArr);
      result = result.map(element => path.resolve(__dirname, `src/lib/bs4/${element}`));

      // Path to the first file in the queue (src/..)
      if (!args['path']) {
        console.log(' ******* Path to main stylesheet NOT added ******* ');
      } else {
        console.log(' ******* Path to main stylesheet ADDED ******* ');
        result.unshift(path.resolve(__dirname, args['path']));
      }

      // console.log(args['path'])
      // console.log(result)

      resolve({
        mode: devMode ? 'development' : 'production',
        entry: {
          // main: './src/principal.js',
          // bundle.css
          bundle: result,
        },
        output: {
          // filename: 'principal.js',
          path: path.resolve(__dirname, 'bundle-css'),
        },
        optimization: {
          minimizer: devMode ? [] : [
            new OptimizeCssAssetsPlugin({
              assetNameRegExp: /\.css$/,
            })
          ]
        },  
        module: {
          rules: [
            {
              test: /\.(sa|sc|c)ss$/,
              use: [
                MiniCssExtractPlugin.loader, // 3. Extract css into files
                'css-loader', // 2. Turns css into commonjs
                'sass-loader' // 1. Turns sass into css
              ]
            },
            {
              test: /.(svg|png|jpe?g|gif)$/,
              use: [
                {
                  loader: 'file-loader',
                  options: {
                    name: '[name].[ext]',
                    outputPath: 'images/',
                  }
                }
              ]
            },
            {
              test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
              use: [
                {
                  loader: 'file-loader',
                  options: {
                    name: '[name].[ext]',
                    outputPath: 'fonts/',
                    exclude: /images/, // avoid having copies of .svg fonts into 'images/'
                  }
                }
              ]
            }
          ],
        },
        plugins: [
          new MiniCssExtractPlugin({
            filename: devMode ? '[name].[hash].css' : '[name].[hash].min.css'
          }),
          new CleanWebpackPlugin({
            cleanAfterEveryBuildPatterns: ['bundle-css'] // clean output.path directory
          })
        ]
      })
    })
  })

module.exports = configPromise

这是我用来运行它的命令,以防有人也需要帮助:

  "scripts": {
    "bundle-css-dev": "cross-env NODE_ENV=development webpack --config ./bundle-css.config.js --progress --colors",
    "bundle-css-prod": "cross-env NODE_ENV=production webpack --config ./bundle-css.config.js --progress --colors"
  },

要运行以下脚本之一:npm运行bundle-css-dev---path =“ path_to_first_file_in_queue”

1 个答案:

答案 0 :(得分:0)

您可以从 webpack.config.js 导出函数并返回承诺。

Webpack将等待承诺解决:

const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const ext = require('./recursive')

module.exports = () => {
  return ext.files
    .then((result) => {
      return new Promise((resolve, reject) => {
        resolve(promises = result.map(e => e = path.resolve(__dirname, `src/lib/bs4/${e}`)))
        // .map(e => e.replace(/\\/g, '/')))
      })
    })
    .then((result) => {
      console.log(result) // prints out the expected array of file paths!

      return {
        entry: {
          bundle: result,
          main: [
            path.resolve(__dirname, 'src/principal')
          ]
        },
        output: {
          filename: '[name].js',
          path: path.resolve(__dirname, 'dist'),
        },
        module: {
          rules: [
            {
              test: /\.(sa|sc|c)ss$/,
              use: [
                MiniCssExtractPlugin.loader,
                'css-loader',
                'sass-loader'
              ]
            },
          ],
        },
        plugins: [
          new MiniCssExtractPlugin({
            filename: "[name].css"
          }),
        ]
      }
    })
}