webpack中的嵌套输出路径无法正常工作

时间:2018-06-06 17:04:23

标签: reactjs configuration webpack-4

这是我的生产模式webpack配置文件:

const autoprefixer = require("autoprefixer")
const webpack = require("webpack")
const HtmlWebpackPlugin = require("html-webpack-plugin")
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
const ManifestPlugin = require("webpack-manifest-plugin")
const InterpolateHtmlPlugin = require("react-dev-utils/InterpolateHtmlPlugin")
const url = require("url")
const paths = require("./paths")
const getClientEnvironment = require("./env")
const OfflinePlugin = require("offline-plugin")
const UglifyJsPlugin = require("uglifyjs-webpack-plugin")
const path = require("path")
const WriteFilePlugin = require("write-file-webpack-plugin")
const cssHelper = require("../src/components/Server/serverCssBuilder")

function ensureSlash(path, needsSlash) {
  const hasSlash = path.endsWith("/")
  if (hasSlash && !needsSlash) {
    return path.substr(path, path.length - 1)
  } else if (!hasSlash && needsSlash) {
    return `${path}/`
  }
  return path
}

const homepagePath = require(paths.appPackageJson).homepage
const homepagePathname = homepagePath ? url.parse(homepagePath).pathname : "/"
const publicPath = ensureSlash(homepagePathname, true)
const publicUrl = ensureSlash(homepagePathname, false)
const env = getClientEnvironment(publicUrl)
const analyticUrl1 = env["process.env"].analyticUrl1
const analyticUrl2 = env["process.env"].analyticUrl2

// Assert this just to be safe.
// Development builds of React are slow and not intended for production.
if (env["process.env"].NODE_ENV !== "\"production\"") {
  throw new Error("Production builds must have NODE_ENV=production.")
}

// This is the production configuration.
// It compiles slowly and is focused on producing a fast and minimal bundle.
// The development configuration is different and lives in a separate file.
const browserConfig = {
  // Don't attempt to continue if there are any errors.
  bail: true,
  mode: "production",
  optimization: {
    //minimize: true,
    splitChunks: {
      chunks: "async",
      cacheGroups: {
        commons: {
          test: /[\\/]node_modules[\\/]/,
          name: "vendor",
          chunks: "all",
        },
      },
    },
    minimizer: [
      new UglifyJsPlugin({
        uglifyOptions: {
          compress: true,
          ecma: 6,
          output: {
            comments: false,
          },
          compess: {
            dead_code: true,
            drop_console: true,
          },
        },
        sourceMap: false,
      }),
    ],
  },
  // In production, we only want to load the polyfills and the app code.
  entry: {
    bundle: [
      require.resolve("./polyfills"),
      paths.appIndexJs,
    ],
    vendor: [
      "react",
      "lodash",
      "moment",
    ],
  },
  output: {
    path: path.resolve(__dirname, "../build"),
    filename: "static/js/[name].[hash:8].js",
    chunkFilename: "static/js/[name].[hash:8].chunk.js",
    publicPath,
  },
  resolve: {
    extensions: [".js", ".json", ".jsx", "*"],
    alias: {
      // Support React Native Web
      // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
      "react-native": "react-native-web",
    },
    modules: ["src", "node_modules"],
  },

  module: {
    rules: [
      // First, run the linter.
      // It's important to do this before Babel processes the JS.
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        loader: "eslint-loader",
        include: paths.appSrc,
        enforce: "pre",
      },
      {
        exclude: [
          /\.html$/,
          /\.(js|jsx)$/,
          /\.css$/,
          /\.json$/,
          /\.svg$/,
        ],
        // loader, query and exclude
        loader: "url-loader",
        options: {
          limit: 10000,
          name: "static/media/[name].[hash:8].[ext]",
        },
      },
      // Process JS with Babel.
      {
        test: /\.(js|jsx)$/,
        include: paths.appSrc,
        loader: "babel-loader?cacheDirectory=true",
      },
      // "postcss" loader applies autoprefixer to our CSS.
      // "css" loader resolves paths in CSS and adds assets as dependencies.
      // "style" loader turns CSS into JS modules that inject <style> tags.
      // In production, we use a plugin to extract that CSS to a file, but
      // in development "style" loader enables hot editing of CSS.
      {
        test: /\.css$/,
        use: [
          "style-loader",
          {
            loader: "css-loader",
            options: {
              importLoaders: 1,
              minimize: true,
            },
          },
          "postcss-loader",
          "sass-loader",
        ],
        // Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
      },
      // JSON is not enabled by default in Webpack but both Node and Browserify
      // allow it implicitly so we also enable it.
      {
        test: /\.json$/,
        loader: "json-loader",
      },
      // "file" loader for svg
      {
        test: /\.svg$/,
        loader: "file-loader",
        options: {
          name: "static/media/[name].[hash:8].[ext]",
        },
      },
    ],
  },
  plugins: [
    //eslint-disable-next-line
    new HtmlWebpackPlugin({
      inject: true,
      template: paths.appHtml,
      //eslint-disable-next-line
      fileDtm: analyticUrl1.substr(1, analyticUrl1.length - 2),
      analyticUrl2,
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeRedundantAttributes: true,
        useShortDoctype: true,
        removeEmptyAttributes: true,
        removeStyleLinkTypeAttributes: true,
        keepClosingSlash: true,
        minifyJS: true,
        minifyCSS: true,
        minifyURLs: true,
      },
    }),
    new WriteFilePlugin(),
    new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en/),
    new webpack.LoaderOptionsPlugin({
      options: {
        postcss: [
          autoprefixer({
            browsers: [
              ">1%",
              "last 4 versions",
              "Firefox ESR",
              "not ie < 9", // React doesn't support IE8 anyway
            ],
          }),
        ],
      },
    }),
    new InterpolateHtmlPlugin({
      PUBLIC_URL: publicUrl,
    }),
    new webpack.DefinePlugin(env),
    new webpack.optimize.OccurrenceOrderPlugin(),

    new MiniCssExtractPlugin({
      filename: "[name].[hash].css",
      path: "static/css/",
    }),
    //new ExtractTextPlugin("static/css/[name].[contenthash:8].css"),
    new ManifestPlugin({
      fileName: "asset-manifest.json",
    }),
    new OfflinePlugin({
      // serviceWorker: {
      //   minify: false,
      // },
      relativePaths: false,
      publicPath: "/",

      // No need to cache .htaccess. See http://mxs.is/googmp,
      // this is applied before any match in `caches` section
      excludes: [".htaccess", "**/*.map"],

      caches: {
        main: [":rest:"],

        // All chunks marked as `additional`, loaded after main section
        // and do not prevent SW to install. Change to `optional` if
        // do not want them to be preloaded at all (cached only when first loaded)
        optional: ["*.chunk.js"],
      },

      // Removes warning for about `additional` section usage
      safeToUseOptionalCaches: true,

      AppCache: false,
    }),
    // new UglifyJsPlugin(),
  ],
  // Some libraries import Node modules but don't use them in the browser.
  // Tell Webpack to provide empty mocks for them so importing them works.
  node: {
    fs: "empty",
    net: "empty",
    tls: "empty",
  },
}

const serverConfig = {
  mode: "production",
  optimization: {
    //minimize: true,
    splitChunks: {
      chunks: "async",
      cacheGroups: {
        commons: {
          test: /[\\/]node_modules[\\/]/,
          name: "vendor",
          chunks: "all",
        },
      },
    },
    minimizer: [
      new UglifyJsPlugin({
        uglifyOptions: {
          compress: true,
          ecma: 6,
          output: {
            comments: false,
          },
          compess: {
            dead_code: true,
            drop_console: true,
          },
        },
        sourceMap: false,
      }),
    ],
  },
  entry: {
    server: path.resolve(__dirname, "../script/server_script.js"),
    testCss: cssHelper.geTestCss(__dirname),

  },
  target: "node",
  output: {
    path: path.resolve(__dirname, "../build"),
    filename: "[name].js",
    libraryTarget: "commonjs2",
  },
  module: {
    rules: [
      {
        exclude: [
          /\.html$/,
          /\.(js|jsx)$/,
          /\.css$/,
          /\.json$/,
          /\.svg$/,
        ],
        // loader, query and exclude
        loader: "url-loader",
        options: {
          limit: 10000,
          name: "/static/media/[name].[hash:8].[ext]",
        },
      },
      {
        test: /\.svg$/,
        loader: "file-loader",
        options: {
          name: "/static/media/[name].[hash:8].[ext]",
        },
      },
      {
        test: /\.css$/,
        use: [
          "style-loader",
          "css-loader",
          "postcss-loader",
          "sass-loader",
        ],
        // Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
      },
      {
        test: /\.scss$/,
        use: [
          {
            loader: "css-loader/locals",
          },
        ],
      },
      {
        test: /js$/,
        exclude: /(node_modules)/,
        loader: "babel-loader",
        query: { presets: ["react", "es2016", "es2015"], plugins: ["transform-class-properties"] },
      },
      {
        test: /jsx?$/,
        exclude: /(node_modules)/,
        loader: "babel-loader",
        query: { presets: ["react", "es2016", "es2015"], plugins: ["transform-class-properties"] },
      },
    ],
  },
  plugins: [
    new webpack.DefinePlugin(env),
    new WriteFilePlugin(),
    // This helps ensure the builds are consistent if source hasn't changed:
    new webpack.optimize.OccurrenceOrderPlugin(),
    // Try to dedupe duplicated modules, if any:
    // new webpack.optimize.DedupePlugin(),
    // Minify the code.
    // new webpack.optimize.UglifyJsPlugin({
    //   compress: {
    //     screw_ie8: true, // React doesn't support IE8
    //     warnings: false,
    //   },
    //   mangle: {
    //     screw_ie8: true,
    //   },
    //   output: {
    //     comments: false,
    //     screw_ie8: true,
    //   },
    // }),
    //new UglifyJsPlugin(),
    new MiniCssExtractPlugin({
      filename: "[name].css",
      path: "static/css/",
    }),
    //new ExtractTextPlugin("static/css/[name].css"),
    new webpack.LoaderOptionsPlugin({
      options: {
        postcss: [
          autoprefixer({
            browsers: [
              ">1%",
              "last 4 versions",
              "Firefox ESR",
              "not ie < 9", // React doesn't support IE8 anyway
            ],
          }),
        ],
      },
    }),
  ],
  resolve: {
    modules: ["src", "node_modules"],
  },
}

module.exports = [browserConfig, serverConfig]
  

在build.js文件中

这是我的配置,基本上。当我运行webpack([browserConfig,serverConfig])。run(()=&gt; { //成功或失败时控制台的其他逻辑 })

运行此节点build.js时。它不会在构建中创建文件夹 我希望build文件夹有&#34; static / js / [filenames]&#34;和staic / css [filename]

我正在尝试将我的项目从webpack 2.x升级到&#34; webpack&#34;:&#34; ^ 4.10.2&#34;。我在每个地方都阅读它并检查我的配置。但仍然无法找到,我做错了什么。如果有些人指出配置中的任何错误,那将会很有帮助。

0 个答案:

没有答案