Internet Explorer 11 和 webpack V3 - 不捆绑 css 变量

Internet explorer 11 & webpack V3 - doesn't bundle css variables

我正在开发一个与 webpack 捆绑在一起的 React\Redux 项目。

webpack V1 升级到 V3 后,IE (11) 支持被破坏,部分元素有附加的 css 规则,IE 无法处理。
在 google chrome 一切正常。

package.json:

{
  "name": "react-tutorials",
  "version": "0.0.0",
  "description": "Javelin UI",
  "main": "webpack.config.js",
  "dependencies": {
    "babel-core": "^6.26.3",
    "babel-plugin-transform-react-remove-prop-types": "^0.4.24",
    "babel-polyfill": "^6.26.0",
    "babel-preset-env": "^1.7.0",
    "base64-js": "^1.3.0",
    "body-parser": "1.15.0",
    "classnames": "2.2.3",
    "copy-to-clipboard": "^3.0.8",
    "core-js": "^2.6.9",
    "cryptr": "^4.0.2",
    "dateformat": "^1.0.12",
    "es6-promise": "^3.1.2",
    "es6-shim": "0.35.0",
    "file-saver": "^1.3.8",
    "flux": "^2.1.1",
    "griddle-react": "^0.8.2",
    "history": "^1.17.0",
    "lodash": "^4.17.11",
    "material-ui": "^0.17.4",
    "minify": "^4.1.1",
    "moment": "^2.24.0",
    "react": "^15.6.2",
    "react-bootstrap": "^0.32.0",
    "react-collapsible": "^1.5.0",
    "react-datepicker": "^0.57.0",
    "react-dom": "^15.6.2",
    "react-easy-transition": "^1.2.6",
    "react-fontawesome": "^1.6.1",
    "react-keydown": "1.4.9",
    "react-list": "^0.8.8",
    "react-redux": "^4.4.10",
    "react-router": "^3.2.0",
    "react-router-redux": "^4.0.4",
    "react-s-alert": "^1.4.1",
    "react-tagsinput": "^3.19.0",
    "react-tap-event-plugin": "^2.0.1",
    "react-timeago": "^3.1.0",
    "react-toggle-button": "^2.1.0",
    "react-toolbox": "^2.0.0-beta.13",
    "react-tooltip": "^3.10.0",
    "redux": "^3.7.2",
    "redux-create-reducer": "1.1.0",
    "reselect": "2.3.0",
    "seamless-immutable": "^6.0.0",
    "socket.io-client": "^2.2.0",
    "string-replace-webpack-plugin": "0.0.4",
    "subnet-info": "0.0.2",
    "universal-cookie": "^2.1.2",
    "webpack-replace": "^1.0.0",
    "whatwg-fetch": "^0.11.0"
  },
  "devDependencies": {
    "babel-loader": "^6.4.1",
    "babel-plugin-add-module-exports": "^0.1.2",
    "babel-plugin-react-html-attrs": "^2.1.0",
    "babel-plugin-transform-class-properties": "^6.24.1",
    "babel-plugin-transform-decorators-legacy": "^1.3.5",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react": "^6.24.1",
    "babel-preset-stage-0": "^6.24.1",
    "babel-preset-stage-1": "6.5.0",
    "css-loader": "^0.28.11",
    "less": "^3.9.0",
    "less-loader": "^5.0.0",
    "node-sass": "^4.12.0",
    "postcss-loader": "^0.8.1",
    "sass-loader": "^3.1.2",
    "string-replace-loader": "^1.3.0",
    "style-loader": "^0.13.2",
    "uglifyjs-webpack-plugin": "^1.3.0",
    "url-loader": "^0.6.2",
    "webpack": "^3.11.0",
    "webpack-dev-server": "^1.16.5"
  },
  "scripts": {
    "dev": "node_modules/.bin/webpack-dev-server --lazy --progress",
    "hot": "node_modules/.bin/webpack-dev-server --hot --progress",
    "mockServer": "cd mockserver && nodemon server.js",
    "build": "set NODE_ENV=production&& webpack --progress --colors --define process.env.NODE_ENV='\"production\"'",
    "test": "NODE_ENV=test node_modules/.bin/karma start",
    "cov": "open coverage/report-html/index.html"
  },
  "author": "",
  "license": "ISC"
}

webpack.config.js:

var debug      = process.env.NODE_ENV !== 'production';
var webpack    = require('webpack');
var path       = require('path');
const srcPath  = path.join(__dirname, "src");
const jsPath   = path.join(srcPath, "js");
const cssPath  = path.join(srcPath, "css");
const testPath = path.join(__dirname, 'spec');
const distPath = path.join(__dirname, 'dist');
autoprefixer   = require('autoprefixer');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')

const appEnv   = process.env.NODE_ENV || 'development';

//getting the commit sha and sending it UI
var childProcess = require('child_process');
const VERSION = childProcess.execSync('git rev-parse HEAD').toString().replace(/(\r\n|\n|\r)/gm,"");

const plugins = [
  new webpack.DefinePlugin({ $_ENVIRONMENT: JSON.stringify(appEnv) })
];
const devPlugins = [];
const prodPlugins = [
  new UglifyJsPlugin({uglifyOptions: { mangle: false, sourceMap: false }})
];

module.exports = {
  context: srcPath,
  devtool: debug ? "inline-sourcemap" : false,
  entry: "./js/client.js",
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: ['react', 'es2015', 'stage-0', 'stage-1'],
              plugins: ['react-html-attrs', 'transform-class-properties', 'transform-decorators-legacy'],
            }
          }
        ],
      },
      {
        test: /\.css$/,
        use: [
          "style-loader",
          {
            loader: "css-loader",
            options: {
              modules: true, // default is false
              sourceMap: true,
              importLoaders: 1,
              import: true,
              localIdentName: "[name]--[local]--[hash:base64:8]"
            }
          },
          'sass-loader',
          "postcss-loader"
        ]
      },
      {
        test: /\.scss$/,
        use: [
          {
            loader: 'style-loader'
          },
          {
            loader: 'css-loader?root=' + encodeURIComponent(cssPath) + '&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5],'
          },
          {
            loader: 'sass-loader'
          },
          {
            loader: 'postcss-loader'
          }
        ]
      },
      // Allow `require`ing image/font files (also when included in CSS)
      // Inline assets under 5kb as Base64 data URI, otherwise uses `file-loader`
      {
        test: /\.(eot|woff2?|ttf|otf)(\?.*)?$/i,
        use: 'url-loader?limit=5120&name=[path][name].[hash].[ext]'
      },

      {
        test: /\.(jpe?g)(\?.*)?$/i,
        use: 'url-loader?limit=5120&name=[path][name].[hash].[ext]'
      },
      {
        test: /\.(svg|gif|png)$/i,
        use: 'url-loader',
      }
    ]
  },
  output: {
    path: distPath,
    publicPath: '/',
    filename: "client.min.js"
  },
  resolve: {
    modules: ['node_modules',jsPath, cssPath, testPath],
    extensions: ['*', '.js', '.jsx', '.json', '.scss'],
  },
  plugins: plugins.concat(debug ? devPlugins : prodPlugins),
  devServer: {
    contentBase: srcPath,
    colors: true,
    noInfo: false,
    inline: true,
    historyApiFallback: true
  }
};

通过更新和添加一些节点包解决了这个问题。

package.json

  {
  "name": "react-tutorials",
  "version": "0.0.0",
  "description": "Javelin UI",
  "main": "webpack.config.js",
  "dependencies": {
    "babel-core": "^6.26.3",
    "babel-plugin-transform-react-remove-prop-types": "^0.4.24",
    "babel-polyfill": "^6.26.0",
    "babel-preset-env": "^1.7.0",
    "base64-js": "^1.3.0",
    "body-parser": "1.15.0",
    "classnames": "2.2.3",
    "copy-to-clipboard": "^3.0.8",
    "core-js": "^2.6.9",
    "cryptr": "^4.0.2",
    "dateformat": "^1.0.12",
    "es6-promise": "^3.1.2",
    "es6-shim": "0.35.0",
    "file-saver": "^1.3.8",
    "flux": "^2.1.1",
    "griddle-react": "^0.8.2",
    "history": "^1.17.0",
    "lodash": "^4.17.11",
    "material-ui": "^0.17.4",
    "minify": "^4.1.1",
    "moment": "^2.24.0",
    "postcss-import": "^12.0.1",
    "postcss-preset-env": "^6.6.0",
    "react": "^15.6.2",
    "react-app-polyfill": "^1.0.1",
    "react-bootstrap": "^0.32.0",
    "react-collapsible": "^1.5.0",
    "react-datepicker": "^0.57.0",
    "react-dom": "^15.6.2",
    "react-easy-transition": "^1.2.6",
    "react-fontawesome": "^1.6.1",
    "react-keydown": "1.4.9",
    "react-list": "^0.8.8",
    "react-redux": "^4.4.10",
    "react-router": "^3.2.0",
    "react-router-redux": "^4.0.4",
    "react-s-alert": "^1.4.1",
    "react-tagsinput": "^3.19.0",
    "react-tap-event-plugin": "^2.0.1",
    "react-timeago": "^3.1.0",
    "react-toggle-button": "^2.1.0",
    "react-toolbox": "^2.0.0-beta.13",
    "react-tooltip": "^3.10.0",
    "redux": "^3.7.2",
    "redux-create-reducer": "1.1.0",
    "reselect": "2.3.0",
    "seamless-immutable": "^6.0.0",
    "socket.io-client": "^2.2.0",
    "string-replace-webpack-plugin": "0.0.4",
    "subnet-info": "0.0.2",
    "sugarss": "^2.0.0",
    "universal-cookie": "^2.1.2",
    "webpack-replace": "^1.0.0",
    "whatwg-fetch": "^0.11.0"
  },
  "devDependencies": {
    "babel-loader": "^6.4.1",
    "babel-plugin-add-module-exports": "^0.1.2",
    "babel-plugin-react-html-attrs": "^2.1.0",
    "babel-plugin-transform-class-properties": "^6.24.1",
    "babel-plugin-transform-decorators-legacy": "^1.3.5",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react": "^6.24.1",
    "babel-preset-stage-0": "^6.24.1",
    "babel-preset-stage-1": "6.5.0",
    "css-loader": "^0.28.11",
    "cssnano": "^4.1.10",
    "less": "^3.9.0",
    "less-loader": "^5.0.0",
    "node-sass": "^4.12.0",
    "postcss-loader": "^3.0.0",
    "sass-loader": "^3.1.2",
    "string-replace-loader": "^1.3.0",
    "style-loader": "^0.23.1",
    "uglifyjs-webpack-plugin": "^1.3.0",
    "url-loader": "^0.6.2",
    "webpack": "^3.11.0",
    "webpack-dev-server": "^1.16.5"
  },
  "scripts": {
    "dev": "node_modules/.bin/webpack-dev-server --lazy --progress",
    "hot": "node_modules/.bin/webpack-dev-server --hot --progress",
    "mockServer": "cd mockserver && nodemon server.js",
    "build": "set NODE_ENV=production&& webpack --progress --colors --define process.env.NODE_ENV='\"production\"'",
    "test": "NODE_ENV=test node_modules/.bin/karma start",
    "cov": "open coverage/report-html/index.html"
  },
  "author": "",
  "license": "ISC"
}

webpack.config.js

var debug      = process.env.NODE_ENV !== 'production';
var webpack    = require('webpack');
var path       = require('path');
const srcPath  = path.join(__dirname, "src");
const jsPath   = path.join(srcPath, "js");
const cssPath  = path.join(srcPath, "css");
const testPath = path.join(__dirname, 'spec');
const distPath = path.join(__dirname, 'dist');
autoprefixer   = require('autoprefixer');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')

const appEnv   = process.env.NODE_ENV || 'development';

//getting the commit sha and sending it UI
var childProcess = require('child_process');
const VERSION = childProcess.execSync('git rev-parse HEAD').toString().replace(/(\r\n|\n|\r)/gm,"");

const plugins = [
  new webpack.DefinePlugin({ $_ENVIRONMENT: JSON.stringify(appEnv) })
];
const devPlugins = [];
const prodPlugins = [
  new UglifyJsPlugin({uglifyOptions: { mangle: false, sourceMap: false }})
];

module.exports = {
  context: srcPath,
  devtool: debug ? "inline-sourcemap" : false,
  entry: "./js/client.js",
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: ['react', 'es2015', 'stage-0', 'stage-1'],
              plugins: ['react-html-attrs', 'transform-class-properties', 'transform-decorators-legacy'],
            }
          }
        ],
      },
      {
        test: /\.jsx?$/,
        use: [
          {
            loader: 'string-replace-loader',
            options: {
              search: 'COMMIT_SHA_ANCHOR',
              replace: VERSION
            }
          }
        ],
      },
      {
        test: /\.css$/,
        use: [
          "style-loader",
          {
            loader: "css-loader",
            options: {
              modules: true, // default is false
              sourceMap: true,
              importLoaders: 1,
              import: true,
              localIdentName: "[name]--[local]--[hash:base64:8]"
            }
          },
          'sass-loader',
          "postcss-loader"
        ]
      },
      {
        test: /\.scss$/,
        use: [
          {
            loader: 'style-loader'
          },
          {
            loader: 'css-loader?root=' + encodeURIComponent(cssPath) + '&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5],'
          },
          {
            loader: 'sass-loader'
          },
          {
            loader: 'postcss-loader'
          }
        ]
      },
      // Allow `require`ing image/font files (also when included in CSS)
      // Inline assets under 5kb as Base64 data URI, otherwise uses `file-loader`
      {
        test: /\.(eot|woff2?|ttf|otf)(\?.*)?$/i,
        use: 'url-loader?limit=5120&name=[path][name].[hash].[ext]'
      },

      {
        test: /\.(jpe?g)(\?.*)?$/i,
        use: 'url-loader?limit=5120&name=[path][name].[hash].[ext]'
      },
      {
        test: /\.(svg|gif|png)$/i,
        use: 'url-loader',
      }
    ]
  },
  output: {
    path: distPath,
    publicPath: '/',
    filename: "client.min.js"
  },
  resolve: {
    modules: ['node_modules',jsPath, cssPath, testPath],
    extensions: ['*', '.js', '.jsx', '.json', '.scss'],
  },
  plugins: plugins.concat(debug ? devPlugins : prodPlugins),
  devServer: {
    contentBase: srcPath,
    colors: true,
    noInfo: false,
    inline: true,
    historyApiFallback: true
  }
};

还添加了:
.babelrc

  {
  "presets": [
    ["env", {
      "modules": 'commonjs',
      "targets": {
        "browsers": [
          "> 1%",
          "Firefox >= 52", // last ESR
          "IE 11"
        ]
      },
      "useBuiltIns": true
    }]
  ]
}

postcss.config.js

module.exports = {
  plugins: {
    'postcss-preset-env': {},
    'cssnano': {}
  }
}

请将IE设为非法...