2

我正在通过中间人静态生成器构建一系列小部件,并且遇到了 Webpack 配置问题。这是目标。

  • 每个小部件都需要有自己的 JS 和 CSS 文件
  • 小部件应该共享全局配置并且只处理单独的抽象
  • 小部件配置存储在一个名为webpack-configurations

webpack.config.js这是我正在修改的基本文件...

"use strict";

const path = require("path");
const webpack = require("webpack");
const merge = require('webpack-merge');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const ManifestPlugin = require("webpack-manifest-plugin");
const outputPath = path.join(__dirname, "build/assets");

const globalConfig = {
  output: {
    path: outputPath
  },

  resolve: {
    modules: [
      "node_modules"
    ]
  },

  module: {
    rules: [
      {
        test: /\.html$/,
        exclude: /(assets)/,
        use: [
          {
            loader: "html-loader",
            options: {
              minimize: true,
              removeComments: false,
              collapseWhitespace: false,
              name: "[name]-[hash].[ext]",
              publicPath: "/assets/"
            }
          }
        ]
      },
      {
        test: /\.(woff|woff2|eot|ttf|svg|ico|jpg|jpeg|png)$/,
        use: [
          {
            loader: "url-loader",
            options: {
              limit: 5000,
              name: "[name]-[hash].[ext]",
              publicPath: "/assets/"
            }
          }
        ]
      },
      {
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/,
        use: [
          {
            loader: "babel-loader",
            options: {
              presets: ["es2015"]
            }
          }
        ]
      },
      {
        test: /\.(css|scss)$/,
        use: [
          {
            loader: "file-loader",
            options: {
              name: "[name]-[hash].css",
              publicPath: "/assets/"
            }
          },
          {
            loader: "extract-loader"
          },
          {
            loader: "css-loader"
          },
          {
            loader: "resolve-url-loader"
          },
          {
            loader: "sass-loader",
            options: {
              includePaths: [
                path.resolve(__dirname, "node_modules"),
              ]
            }
          }
        ]
      }
    ]
  },

  plugins: [
    new ManifestPlugin({
      fileName: "rev-manifest.json"
    }),
    new webpack.ProvidePlugin({
      $: "jquery",
      jQuery: "jquery",
      "window.jQuery": "jquery"
    }),
    new CleanWebpackPlugin([outputPath], {
      root: __dirname
    })
  ]
};


const interactiveOneConfig = {
  entry: {
    site: [
      path.join(__dirname, "/source/assets/javascripts/global.js"),
      path.join(__dirname, "/source/assets/javascripts/interactive-one/interactive-one.js"),
      path.join(__dirname, "/source/assets/stylesheets/interactive-one/interactive-one.scss"),
    ]
  },

  output: {
    filename: "interactive-one-[hash].js"
  }
};


const interactiveTwoConfig = {
  entry: {
    site: [
      path.join(__dirname, "/source/assets/javascripts/global.js"),
      path.join(__dirname, "/source/assets/javascripts/interactive-two/interactive-two.js"),
      path.join(__dirname, "/source/assets/stylesheets/interactive-two/interactive-two.scss"),
    ]
  },

  output: {
    filename: "interactive-two-[hash].js"
  }
};

module.exports = [
  merge.smart(globalConfig, interactiveOneConfig),
  merge.smart(globalConfig, interactiveTwoConfig)
];

这是一个单独配置的示例...

const path = require("path");
const interactiveOneConfig = {
  entry: {
    site: [
      path.join(__dirname, "/source/assets/javascripts/global.js"),
      path.join(__dirname, "/source/assets/javascripts/interactive-one/interactive-one.js"),
      path.join(__dirname, "/source/assets/stylesheets/interactive-one/interactive-one.scss"),
    ]
  },

  output: {
    filename: "interactive-one-[hash].js"
  }
}

...和往常一样,这是我的package.json文件

{
  "scripts": {
    "start": "NODE_ENV=development webpack --watch -d --progress --color",
    "build": "NODE_ENV=production webpack --bail -p"
  },
  "dependencies": {
    "jquery": "^3.3.1",
    "normalize-scss": "^7.0.1",
    "webpack-merge": "^4.1.2"
  },
  "devDependencies": {
    "babel": "^6.23.0",
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-stage-0": "^6.24.1",
    "clean-webpack-plugin": "^0.1.18",
    "css-loader": "^0.28.9",
    "extract-loader": "^1.0.2",
    "extract-text-webpack-plugin": "^3.0.2",
    "file-loader": "^1.1.6",
    "html-loader": "^0.5.5",
    "node-sass": "^4.7.2",
    "postcss-loader": "^2.1.0",
    "precss": "^3.1.0",
    "resolve-url-loader": "^2.2.1",
    "sass-loader": "^6.0.6",
    "script-loader": "^0.7.2",
    "style-loader": "^0.20.1",
    "url-loader": "^0.6.2",
    "webpack": "^3.11.0",
    "webpack-manifest-plugin": "^1.3.2"
  }
}

在 Webpack 中,如何将这两个常量提取到它们自己的文件中,导入它们并运行构建过程?

const interactiveOneConfig = {
  entry: {
    site: [
      path.join(__dirname, "/source/assets/javascripts/global.js"),
      path.join(__dirname, "/source/assets/javascripts/interactive-one/interactive-one.js"),
      path.join(__dirname, "/source/assets/stylesheets/interactive-one/interactive-one.scss"),
    ]
  },

  output: {
    filename: "interactive-one-[hash].js"
  }
};


const interactiveTwoConfig = {
  entry: {
    site: [
      path.join(__dirname, "/source/assets/javascripts/global.js"),
      path.join(__dirname, "/source/assets/javascripts/interactive-two/interactive-two.js"),
      path.join(__dirname, "/source/assets/stylesheets/interactive-two/interactive-two.scss"),
    ]
  },

  output: {
    filename: "interactive-two-[hash].js"
  }
};
4

1 回答 1

1

我用我的爱解决了这个问题,红宝石!

lib/tasks/webpack.rake

namespace :webpack do
  desc 'Build the webpack configuration file'
  task :build do
    puts("---------------------------------------------------------->>\n")
    puts('Building Webpack Configurations...')
    ProcessWebpackConfigurations.new.run
    puts("---------------------------------------------------------->>\n")
  end

  desc 'Remove Generated Webpack File'
  task :delete do
    puts("---------------------------------------------------------->>\n")
    puts('Removing Generated Webpack File')
    puts("---------------------------------------------------------->>\n")
    File.delete('webpack.config.js') if File.exist?('webpack.config.js')
  end
end

lib/modules/process_webpack_configurations.rb

class ProcessWebpackConfigurations
  INSERT_WEBPACK_INTERACTIVE_CONFIGURATIONS = ''
  INSERT_WEBPACK_CONFIGURATION_MERGES = ''
  GLOBAL_WEBPACK_CONFIG_JS = File.read('webpack/global.webpack.config.js')

  attr_reader :insert_webpack_interactive_configurations,
              :insert_webpack_configuration_merges,
              :global_webpack_config_js

  def initialize
    self.global_webpack_config_js = GLOBAL_WEBPACK_CONFIG_JS
    self.insert_webpack_interactive_configurations = INSERT_WEBPACK_INTERACTIVE_CONFIGURATIONS
    self.insert_webpack_configuration_merges = INSERT_WEBPACK_CONFIGURATION_MERGES
  end

  def run
    Dir.glob('webpack/configurations/*.js') do |file|
      process_configuration(file)
      process_configuration_merge(file)
    end

    process_substitution(insert_webpack_interactive_configurations, '{{insert-webpack-interactive-configurations}}')
    process_substitution(trim_excess(insert_webpack_configuration_merges), '{{insert-webpack-configuration-merges}}')

    File.open('webpack.config.js', 'w') { |file| file.write(global_webpack_config_js) }
  end

  private

  attr_writer :insert_webpack_interactive_configurations,
              :insert_webpack_configuration_merges,
              :global_webpack_config_js

  def format_constant_name(str)
    str = str.split('-').map{|e| e.capitalize}.join
    str[0].downcase + str[1..-1]
  end

  def process_configuration(file)
    self.insert_webpack_interactive_configurations = self.insert_webpack_interactive_configurations +
                                                    "\n" +
                                                    File.read(file)
  end

  def process_configuration_merge(file)
    self.insert_webpack_configuration_merges = self.insert_webpack_configuration_merges +
                                              'merge.smart(globalConfig, ' +
                                              format_constant_name(File.basename(file, '.*')) + "),"
  end

  def process_substitution(str_to_use, str_to_replace)
    self.global_webpack_config_js[str_to_replace] = str_to_use
  end

  def trim_excess(str)
    str.slice!(str.length-1,str.length)
    str
  end
end

webpack/configurations/interactive-one-config.js

const interactiveOneConfig = {
  entry: {
    site: [
      path.join(__dirname, "/source/assets/javascripts/global.js"),
      path.join(__dirname, "/source/assets/javascripts/interactive-one/interactive-one.js"),
      path.join(__dirname, "/source/assets/stylesheets/interactive-one/interactive-one.scss"),
    ]
  },

  output: {
    filename: "interactive-one-[hash].js"
  },

  plugins: [
    new ManifestPlugin({
      fileName: "interactive-one-manifest.json"
    })
  ]
};

global.webpack.config.js

"use strict";

const path = require("path");
const webpack = require("webpack");
const merge = require('webpack-merge');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const ManifestPlugin = require("webpack-manifest-plugin");
const outputPath = path.join(__dirname, "build/assets");

const globalConfig = {
  output: {
    path: outputPath
  },

  resolve: {
    modules: [
      "node_modules"
    ]
  },

  module: {
    rules: [
      {
        test: /\.html$/,
        exclude: /(assets)/,
        use: [
          {
            loader: "html-loader",
            options: {
              minimize: true,
              removeComments: false,
              collapseWhitespace: false,
              name: "[name]-[hash].[ext]",
              publicPath: "/assets/"
            }
          }
        ]
      },
      {
        test: /\.(woff|woff2|eot|ttf|svg|ico|jpg|jpeg|png)$/,
        use: [
          {
            loader: "url-loader",
            options: {
              limit: 5000,
              name: "[name]-[hash].[ext]",
              publicPath: "/assets/"
            }
          }
        ]
      },
      {
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/,
        use: [
          {
            loader: "babel-loader",
            options: {
              presets: ["es2015"]
            }
          }
        ]
      },
      {
        test: /\.(css|scss)$/,
        use: [
          {
            loader: "file-loader",
            options: {
              name: "[name]-[hash].css",
              publicPath: "/assets/"
            }
          },
          {
            loader: "extract-loader"
          },
          {
            loader: "css-loader"
          },
          {
            loader: "resolve-url-loader"
          },
          {
            loader: "sass-loader",
            options: {
              includePaths: [
                path.resolve(__dirname, "node_modules"),
              ]
            }
          }
        ]
      }
    ]
  },

  plugins: [
    new webpack.ProvidePlugin({
      $: "jquery",
      jQuery: "jquery",
      "window.jQuery": "jquery"
    }),
    new CleanWebpackPlugin([outputPath], {
      root: __dirname
    })
  ]
};

{{insert-webpack-interactive-configurations}}

module.exports = [{{insert-webpack-configuration-merges}}];
于 2018-04-07T22:45:28.213 回答