Webpack 中的第 3 方 Javascript 和 CSS 文件。奇怪的行为

Posted

技术标签:

【中文标题】Webpack 中的第 3 方 Javascript 和 CSS 文件。奇怪的行为【英文标题】:3rd party Javascript and CSS files in Webpack. Strange behaviour 【发布时间】:2018-10-24 08:06:19 【问题描述】:

我正在使用 MERN 堆栈。我不得不使用一个包含很多标准 js 和 css 文件(jquery、bootstrap、datatables 等)的 3rd 方 html 管理模板。为了将它与 react 集成,我在项目的根目录中创建了一个“公共”文件夹。然后我将 Express 配置为将此文件夹作为静态文件夹提供服务,并将所需的 css 和 html 文件放置在此文件夹中。为了使用它们,我在 index.html 文件的 head 部分添加了 css,在 body 的末尾添加了 js。当我在开发模式下运行服务器并且没有问题时它可以工作。当我在生产模式下运行它时,不知何故布局变得混乱。如果我用 CTRL + F5 刷新它,它会得到修复,但是当我导航到新页面时,它会再次被破坏,我必须再次 CTRL + F5 才能正确显示。

这是我的 webpack.config.dev.js

var webpack = require('webpack');
var cssnext = require('postcss-cssnext');
var postcssFocus = require('postcss-focus');
var postcssReporter = require('postcss-reporter');

module.exports = 
  devtool: 'cheap-module-eval-source-map',

  entry: 
    app: [
      'eventsource-polyfill',
      'webpack-hot-middleware/client',
      'webpack/hot/only-dev-server',
      'react-hot-loader/patch',
      './client/index.js',
    ],
    vendor: [
      'react',
      'react-dom',
    ],
  ,

  output: 
    path: __dirname,
    filename: 'app.js',
    publicPath: 'http://0.0.0.0:8000/',
  ,

  resolve: 
    extensions: ['', '.js', '.jsx'],
    modules: [
      'client',
      'node_modules',
    ],
  ,

  module: 
    loaders: [
      
        test: /\.css$/,
        exclude: /node_modules/,
        loader: 'style-loader!css-loader?localIdentName=[name]__[local]__[hash:base64:5]&modules&importLoaders=1&sourceMap!postcss-loader',
      , 
        test: /\.css$/,
        include: /node_modules/,
        loaders: ['style-loader', 'css-loader'],
      , 
        test: /\.jsx*$/,
        exclude: [/node_modules/, /.+\.config.js/],
        loader: 'babel',
      , 
        test: /\.(jpe?g|gif|png|svg)$/i,
        loader: 'url-loader?limit=10000',
      , 
        test: /\.json$/,
        loader: 'json-loader',
      ,
    ],
  ,

  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.optimize.CommonsChunkPlugin(
      name: 'vendor',
      minChunks: Infinity,
      filename: 'vendor.js',
    ),
    new webpack.DefinePlugin(
      'process.env': 
        CLIENT: JSON.stringify(true),
        'NODE_ENV': JSON.stringify('development'),
      
    ),
  ],

  postcss: () => [
    postcssFocus(),
    cssnext(
      browsers: ['last 2 versions', 'IE > 10'],
    ),
    postcssReporter(
      clearMessages: true,
    ),
  ],
;

这是我的 webpack.config.prod.js

var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var ManifestPlugin = require('webpack-manifest-plugin');
var ChunkManifestPlugin = require('chunk-manifest-webpack-plugin');
var cssnext = require('postcss-cssnext');
var postcssFocus = require('postcss-focus');
var postcssReporter = require('postcss-reporter');
var cssnano = require('cssnano');

module.exports = 
  devtool: 'hidden-source-map',

  entry: 
    app: [
      './client/index.js',
    ],
    vendor: [
      'react',
      'react-dom',
    ]
  ,

  output: 
    path: __dirname + '/dist/client/',
    filename: '[name].[chunkhash].js',
    publicPath: '/',
  ,

  resolve: 
    extensions: ['', '.js', '.jsx'],
    modules: [
      'client',
      'node_modules',
    ],
  ,

  module: 
    loaders: [
      
        test: /\.css$/,
        exclude: /node_modules/,
        loader: ExtractTextPlugin.extract('style-loader', 'css-loader?localIdentName=[hash:base64]&modules&importLoaders=1!postcss-loader'),
      , 
        test: /\.css$/,
        include: /node_modules/,
        loaders: ['style-loader', 'css-loader'],
      , 
        test: /\.jsx*$/,
        exclude: /node_modules/,
        loader: 'babel',
      , 
        test: /\.(jpe?g|gif|png|svg)$/i,
        loader: 'url-loader?limit=10000',
      , 
        test: /\.json$/,
        loader: 'json-loader',
      ,
    ],
  ,

  plugins: [
    new webpack.DefinePlugin(
      'process.env': 
        'NODE_ENV': JSON.stringify('production'),
      
    ),
    new webpack.optimize.CommonsChunkPlugin(
      name: 'vendor',
      minChunks: Infinity,
      filename: 'vendor.js',
    ),
    new ExtractTextPlugin('app.[chunkhash].css',  allChunks: true ),
    new ManifestPlugin(
      basePath: '/',
    ),
    new ChunkManifestPlugin(
      filename: "chunk-manifest.json",
      manifestVariable: "webpackManifest",
    ),
    new webpack.optimize.UglifyJsPlugin(
      compressor: 
        warnings: false,
      
    ),
  ],

  postcss: () => [
    postcssFocus(),
    cssnext(
      browsers: ['last 2 versions', 'IE > 10'],
    ),
    cssnano(
      autoprefixer: false
    ),
    postcssReporter(
      clearMessages: true,
    ),
  ],
;

包.json


  "name": "",
  "version": "2.0.0",
  "description": "",
  "scripts": 
    "test": "cross-env NODE_ENV=test PORT=8080 MONGO_URL=mongodb://localhost:27017/mern-test node_modules/.bin/nyc node --harmony-proxies node_modules/.bin/ava",
    "watch:test": "npm run test -- --watch",
    "cover": "nyc npm run test",
    "check-coverage": "nyc check-coverage --statements 100 --branches 100 --functions 100 --lines 100",
    "start": "cross-env BABEL_DISABLE_CACHE=1 NODE_ENV=development nodemon index.js",
    "start:prod": "cross-env NODE_ENV=production node index.js",
    "bs": "npm run clean && npm run build && npm run build:server && npm run start:prod",
    "build": "cross-env NODE_ENV=production webpack --config webpack.config.prod.js",
    "build:server": "cross-env NODE_ENV=production webpack --config webpack.config.server.js",
    "clean": "rimraf dist",
    "slate": "rimraf node_modules && npm install",
    "lint": "eslint client server"
  ,
  "pre-commit": [
    "lint",
    "test"
  ],
  "repository": 
    "type": "git",
    "url": "git+https://github.com/Hashnode/mern-starter.git"
  ,
  "bugs": 
    "url": "https://github.com/Hashnode/mern-starter/issues"
  ,
  "homepage": "https://github.com/Hashnode/mern-starter#readme",
  "author": "Prashant Abhishek <prashant.abhishek7g@gmail.com>, Mayank Chandola <imayankchd@gmail.com>, Sandeep Panda <sandeep@hashnode.com>, Syed Fazle Rahman <fazle@hashnode.com>, Alkshendra Maurya <alkshendra@hashnode.com>",
  "license": "MIT",
  "dependencies": 
    "babel-core": "^6.9.1",
    "bcrypt-nodejs": "0.0.3",
    "body-parser": "^1.15.1",
    "compression": "^1.6.2",
    "cross-env": "^1.0.8",
    "cuid": "^1.3.8",
    "express": "^4.13.4",
    "intl": "^1.2.4",
    "intl-locales-supported": "^1.0.0",
    "isomorphic-fetch": "^2.2.1",
    "jsonwebtoken": "^8.2.1",
    "limax": "^1.3.0",
    "mongoose": "^4.4.20",
    "morgan": "^1.9.0",
    "passport": "^0.4.0",
    "passport-jwt": "^4.0.0",
    "react": "^15.1.0",
    "react-contexify": "^3.0.0",
    "react-dom": "^15.1.0",
    "react-helmet": "^3.1.0",
    "react-intl": "^2.1.2",
    "react-notify-toast": "^0.4.0",
    "react-redux": "^4.4.5",
    "react-router": "^2.4.1",
    "react-router-dom": "^4.2.2",
    "react-toastify": "^4.0.1",
    "redux": "^3.5.2",
    "redux-thunk": "^2.1.0",
    "sanitize-html": "^1.11.4"
  ,
  "devDependencies": 
    "ava": "^0.15.2",
    "babel-eslint": "^6.0.4",
    "babel-loader": "^6.2.4",
    "babel-plugin-webpack-loaders": "^0.7.0",
    "babel-polyfill": "^6.9.1",
    "babel-preset-es2015": "^6.9.0",
    "babel-preset-es2015-native-modules": "^6.6.0",
    "babel-preset-react": "^6.5.0",
    "babel-preset-react-optimize": "^1.0.1",
    "babel-preset-stage-0": "^6.5.0",
    "babel-register": "^6.9.0",
    "chai": "^3.5.0",
    "chunk-manifest-webpack-plugin": "0.1.0",
    "coveralls": "^2.11.9",
    "css-loader": "^0.23.1",
    "css-modules-require-hook": "^4.0.1",
    "cssnano": "^3.7.0",
    "enzyme": "^2.3.0",
    "eslint": "^2.11.1",
    "eslint-config-airbnb": "^9.0.1",
    "eslint-plugin-ava": "^2.4.0",
    "eslint-plugin-import": "^1.8.1",
    "eslint-plugin-jsx-a11y": "^1.3.0",
    "eslint-plugin-react": "^5.1.1",
    "eventsource-polyfill": "^0.9.6",
    "extract-text-webpack-plugin": "^1.0.1",
    "file-loader": "^0.8.5",
    "jsdom": "^9.2.1",
    "json-loader": "^0.5.4",
    "mock-css-modules": "^1.0.0",
    "mockgoose": "^6.0.3",
    "nock": "^8.0.0",
    "nodemon": "^1.9.2",
    "null-loader": "^0.1.1",
    "nyc": "^6.4.4",
    "postcss-cssnext": "^2.6.0",
    "postcss-focus": "^1.0.0",
    "postcss-loader": "^0.9.1",
    "postcss-reporter": "^1.3.3",
    "pre-commit": "^1.1.3",
    "react-addons-test-utils": "^15.1.0",
    "react-hot-loader": "^3.0.0-beta.2",
    "redux-ava": "^2.0.0",
    "redux-devtools": "^3.3.1",
    "redux-devtools-dock-monitor": "^1.1.1",
    "redux-devtools-log-monitor": "^1.0.11",
    "rimraf": "^2.5.2",
    "script-loader": "^0.7.2",
    "sinon": "^1.17.4",
    "style-loader": "^0.13.1",
    "supertest": "^1.2.0",
    "url-loader": "^0.5.7",
    "webpack": "2.1.0-beta.8",
    "webpack-dev-middleware": "^1.6.1",
    "webpack-dev-server": "^2.1.0-beta.0",
    "webpack-externals-plugin": "^1.0.0",
    "webpack-hot-middleware": "^2.10.0",
    "webpack-manifest-plugin": "^1.0.1"
  ,
  "engines": 
    "node": ">=4"
  ,
  "ava": 
    "files": [
      "client/**/*.spec.js",
      "server/**/*.spec.js"
    ],
    "source": [
      "client/**/*.js",
      "server/**/*.js"
    ],
    "failFast": true,
    "babel": "inherit",
    "require": [
      "./server/util/setup-test-env.js"
    ]
  ,
  "nyc": 
    "include": [
      "client/**/*.js",
      "server/**/*.js"
    ],
    "exclude": [
      "**/*.spec.js",
      "client/reducers.js",
      "client/store.js",
      "client/routes.js",
      "server/util/setup-test-env.js",
      "server/util/test-helpers.js",
      "server/config.js",
      "server/dummyData.js"
    ],
    "reporter": [
      "lcov",
      "text",
      "html"
    ]
  

这可以解决吗?

编辑:即使没有 CTRL + F5 刷新,页面似乎有时也会正确加载。我的直觉告诉我问题在于加载 JS 文件的顺序。关于如何在 dev 和 prod 中保持加载顺序相同的任何提示?

【问题讨论】:

你试过隐身模式吗? @TamasSzoke 是的。相同的行为。当我用 CTRL + F5 刷新时,它加载正常。否则,布局会混乱。 你有活生生的例子吗? @ThiagoLoddi 我有一个活生生的例子,但我已经在开发模式下运行了服务器。我可以私下给你看。你需要从一个活生生的例子中得到什么样的信息?我可以运行它并将你需要的东西发送给你。 您能否发布您的package.json 以查看您正在使用的库版本 【参考方案1】:

如果是webpack.config.prod.js如果看到这部分代码

loader: ExtractTextPlugin.extract('style-loader', 'css-loader?localIdentName=[hash:base64]&modules&importLoaders=1!postcss-loader'),    42.         loader: 'style-loader!css-loader?localIdentName=[name]__[local]__[hash:base64:5]&modules&importLoaders=1&sourceMap!postcss-loader',

只需去掉ExtractTextPlugin.extract,并将这部分代码修改为

'style-loader!css-loader?localIdentName=[name]__[local]__[hash:base64:5]&modules&importLoaders=1&sourceMap!postcss-loader'

【讨论】:

相同的行为。我几乎可以肯定问题出在 JS 文件而不是 CSS 文件上。 是的,我有。没修。检查原始问题,我对其进行了编辑。 你可以使用 head.js (headjs.com) 。如果你想保持脚本加载的顺序。

以上是关于Webpack 中的第 3 方 Javascript 和 CSS 文件。奇怪的行为的主要内容,如果未能解决你的问题,请参考以下文章

在集成 pod 文件之前放置在桥接头中的第 3 方代码该怎么办

vue+webpack入门讲解

Rails webpack 错误:第 3 方 gem 无法解析 jQuery

vuejs code splitting with webpack 3种模式

如何重新加载经常崩溃的第 3 方 DLL

Visual C++:插件 DLL 使用的第 3 方 DLL 的位置?