代码之家  ›  专栏  ›  技术社区  ›  assembler

WebPack 4模块分析失败:意外的标记

  •  0
  • assembler  · 技术社区  · 6 年前

    我有一个基于React样板文件3.7.0的React.js项目,我使用的是它自己的Webpack配置文件,也就是说 webpack.base.babel.js , webpack.dev.babel.js webpack.prod.babel.js . 我在网上寻找解决方案已经有一段时间了,我找不到解决这个问题的方法。在 https://gitter.im/webpack/webpack 横幅上写着:

    如有疑问,请张贴在堆栈溢出上,并使用“webpack”标记

    我又来了。Webpack编译项目时没有错误,也没有开发中的警告(如果我运行 npm start ,但是如果我跑 npm run build npm run-script build 它告诉我:

        > react-boilerplate@3.7.0 prebuild /home/user/project
        > npm run build:clean
    
        > react-boilerplate@3.7.0 build:clean /home/user/project
        > rimraf ./build
    
        > react-boilerplate@3.7.0 build /home/user/project
        > cross-env NODE_ENV=production webpack --config internals/webpack/webpack.prod.babel.js --color -p --progress --hide-modules --display-optimization-bailout
    
        Hash: c6a237769a07ad14e665                                                           
        Version: webpack 4.27.1
        Time: 40850ms
        Built at: 2019-01-28 09:40:17
         250 assets
        Entrypoint main = runtime~main.d96d827d2fca77de74ac.js vendor.4d1e1f30cd3a7c98cfd8.chunk.js main.01e9d47c88b2e7155bd5.chunk.js
    
        ERROR in ./node_modules/jqwidgets-scripts/jqwidgets-react/react_jqxgrid.js 1216:12
        Module parse failed: Unexpected token (1216:12)
        You may need an appropriate loader to handle this file type.
        |     render() {
        |         return (
        >             <div id={this.state.id}>{this.props.value}{this.props.children}</div>
        |         )
        |     };
         @ ./app/containers/xxxxxxx/index.js 38:0-70 343:37-44
         ...
         @ ./app/containers/MainLayout/_nav.js
         @ ./app/containers/MainLayout/index.js
         @ ./app/containers/MainLayout/Loadable.js
         @ ./app/containers/App/index.js
         @ ./app/app.js
         @ multi ./node_modules/react-app-polyfill/ie11.js ./app/app.js
    ...
    

    这是我的 package.json 文件:

    {
      "name": "react-boilerplate",
      "version": "3.7.0",
      "description": "A highly scalable, offline-first foundation with the best DX and a focus on performance and best practices",
      "repository": {
        "type": "git",
        "url": "git://github.com/react-boilerplate/react-boilerplate.git"
      },
      "engines": {
        "npm": ">=5",
        "node": ">=8.10.0"
      },
      "author": "Max Stoiber",
      "license": "MIT",
      "scripts": {
        "analyze:clean": "rimraf stats.json",
        "preanalyze": "npm run analyze:clean",
        "analyze": "node ./internals/scripts/analyze.js",
        "extract-intl": "node ./internals/scripts/extract-intl.js",
        "npmcheckversion": "node ./internals/scripts/npmcheckversion.js",
        "preinstall": "npm run npmcheckversion",
        "prebuild": "npm run build:clean",
        "build": "cross-env NODE_ENV=production webpack --config internals/webpack/webpack.prod.babel.js --color -p --progress --hide-modules --display-optimization-bailout",
        "build:clean": "rimraf ./build",
        "start": "cross-env NODE_ENV=development env-cmd .env node server",
        "start:tunnel": "cross-env NODE_ENV=development ENABLE_TUNNEL=true node server",
        "start:production": "npm run test && npm run build && npm run start:prod",
        "start:prod": "cross-env NODE_ENV=production node server",
        "presetup": "npm i chalk shelljs",
        "setup": "node ./internals/scripts/setup.js",
        "clean": "shjs ./internals/scripts/clean.js",
        "clean:all": "npm run analyze:clean && npm run test:clean && npm run build:clean",
        "generate": "plop --plopfile internals/generators/index.js",
        "lint": "npm run lint:js",
        "lint:css": "stylelint './app/**/*.js'",
        "lint:eslint": "eslint --ignore-path .gitignore --ignore-pattern internals/scripts",
        "lint:eslint:fix": "eslint --ignore-path .gitignore --ignore-pattern internals/scripts --fix",
        "lint:js": "npm run lint:eslint -- . ",
        "lint:staged": "lint-staged",
        "pretest": "npm run test:clean && npm run lint",
        "test:clean": "rimraf ./coverage",
        "test": "cross-env NODE_ENV=test jest --coverage",
        "test:watch": "cross-env NODE_ENV=test jest --watchAll",
        "coveralls": "cat ./coverage/lcov.info | coveralls",
        "prettify": "prettier --write"
      },
      "lint-staged": {
        "*.js": [
          "npm run lint:eslint:fix",
          "git add --force"
        ],
        "*.json": [
          "prettier --write",
          "git add --force"
        ]
      },
      "pre-commit": "lint:staged",
      "resolutions": {
        "babel-core": "7.0.0-bridge.0"
      },
      "dependencies": {
        "@coreui/coreui": "^2.1.4",
        "@coreui/coreui-plugin-chartjs-custom-tooltips": "^1.2.0",
        "@coreui/icons": "^0.3.0",
        "@coreui/react": "^2.1.1",
        "ajv": "^6.6.1",
        "babel-polyfill": "^6.26.0",
        "block-ui": "^2.70.1",
        "bootstrap": "^4.1.3",
        "chalk": "^2.4.1",
        "chart.js": "^2.7.3",
        "classnames": "^2.2.6",
        "compression": "^1.7.3",
        "connected-react-router": "^4.5.0",
        "core-js": "^2.6.0",
        "env-cmd": "^8.0.2",
        "exports-loader": "^0.7.0",
        "flag-icon-css": "^3.2.1",
        "font-awesome": "^4.7.0",
        "fontfaceobserver": "2.0.13",
        "history": "^4.7.2",
        "hoist-non-react-statics": "3.0.1",
        "immutable": "^3.8.2",
        "intl": "^1.2.5",
        "invariant": "^2.2.4",
        "ip": "^1.1.5",
        "is-url-external": "^1.0.3",
        "isnumeric": "^0.3.3",
        "jquery": "^3.3.1",
        "jqwidgets-scripts": "^6.2.0",
        "loadable-components": "^2.2.3",
        "lodash": "^4.17.11",
        "minimist": "1.2.0",
        "moment": "^2.22.2",
        "numeral": "^2.0.6",
        "prop-types": "^15.6.2",
        "react": "^16.6.3",
        "react-chartjs-2": "^2.7.4",
        "react-dom": "^16.6.3",
        "react-helmet": "^5.2.0",
        "react-hot-loader": "^4.6.3",
        "react-intl": "^2.7.2",
        "react-loadable": "^5.5.0",
        "react-redux": "^5.1.1",
        "react-router-dom": "^4.3.1",
        "react-sizeme": "^2.5.2",
        "reactstrap": "^6.5.0",
        "redux": "^4.0.1",
        "redux-immutable": "^4.0.0",
        "redux-saga": "^0.16.2",
        "reselect": "4.0.0",
        "resize-sensor": "0.0.6",
        "sanitize.css": "4.1.0",
        "simple-line-icons": "^2.4.1",
        "styled-components": "^4.1.2",
        "uuid": "^3.3.2",
        "warning": "^4.0.2"
      },
      "devDependencies": {
        "@babel/cli": "7.1.2",
        "@babel/core": "7.1.2",
        "@babel/plugin-proposal-class-properties": "7.1.0",
        "@babel/plugin-proposal-export-namespace-from": "^7.2.0",
        "@babel/plugin-syntax-dynamic-import": "7.0.0",
        "@babel/plugin-transform-modules-commonjs": "7.2.0",
        "@babel/plugin-transform-react-constant-elements": "7.0.0",
        "@babel/plugin-transform-react-inline-elements": "7.0.0",
        "@babel/polyfill": "^7.0.0",
        "@babel/preset-env": "7.1.0",
        "@babel/preset-react": "7.0.0",
        "@babel/register": "7.0.0",
        "add-asset-html-webpack-plugin": "3.1.1",
        "babel-core": "7.0.0-bridge.0",
        "babel-eslint": "10.0.1",
        "babel-loader": "8.0.4",
        "babel-plugin-dynamic-import-node": "2.2.0",
        "babel-plugin-lodash": "3.3.4",
        "babel-plugin-react-intl": "3.0.1",
        "babel-plugin-react-transform": "3.0.0",
        "babel-plugin-styled-components": "1.10.0",
        "babel-plugin-transform-react-remove-prop-types": "0.4.19",
        "circular-dependency-plugin": "5.0.2",
        "compare-versions": "3.4.0",
        "compression-webpack-plugin": "2.0.0",
        "copy-webpack-plugin": "^4.6.0",
        "coveralls": "3.0.2",
        "cross-env": "^5.2.0",
        "css-loader": "1.0.0",
        "enzyme": "3.7.0",
        "enzyme-adapter-react-16": "1.6.0",
        "enzyme-to-json": "3.3.4",
        "eslint": "5.7.0",
        "eslint-config-airbnb": "17.1.0",
        "eslint-config-airbnb-base": "13.1.0",
        "eslint-config-prettier": "3.1.0",
        "eslint-import-resolver-webpack": "0.10.1",
        "eslint-plugin-import": "^2.14.0",
        "eslint-plugin-jsx-a11y": "6.1.2",
        "eslint-plugin-prettier": "3.0.0",
        "eslint-plugin-react": "7.11.1",
        "eslint-plugin-redux-saga": "0.9.0",
        "express": "^4.16.4",
        "file-loader": "2.0.0",
        "html-loader": "0.5.5",
        "html-webpack-plugin": "3.2.0",
        "http-proxy-middleware": "^0.19.1",
        "image-webpack-loader": "^4.6.0",
        "imports-loader": "0.8.0",
        "jest-cli": "23.6.0",
        "jest-styled-components": "6.2.2",
        "lint-staged": "7.3.0",
        "ngrok": "3.1.0",
        "node-plop": "0.16.0",
        "node-sass": "^4.11.0",
        "null-loader": "0.1.1",
        "offline-plugin": "5.0.5",
        "optimize-css-assets-webpack-plugin": "^5.0.1",
        "plop": "2.1.0",
        "pre-commit": "1.2.2",
        "prettier": "1.14.3",
        "react-app-polyfill": "0.1.3",
        "react-test-renderer": "16.6.0",
        "rimraf": "2.6.2",
        "sass-loader": "^7.1.0",
        "shelljs": "^0.8.3",
        "style-loader": "0.23.1",
        "stylelint": "9.6.0",
        "stylelint-config-recommended": "2.1.0",
        "stylelint-config-styled-components": "0.1.1",
        "stylelint-processor-styled-components": "1.5.0",
        "svg-url-loader": "2.3.2",
        "terser-webpack-plugin": "1.1.0",
        "uglifyjs-webpack-plugin": "^2.0.1",
        "url-loader": "1.1.2",
        "webpack": "^4.27.1",
        "webpack-cli": "^3.1.2",
        "webpack-dev-middleware": "3.4.0",
        "webpack-hot-middleware": "2.24.3 ",
        "webpack-pwa-manifest": "3.7.1",
        "whatwg-fetch": "3.0.0"
      }
    }
    

    这是我的 web包.base.babel.js 文件:

    const path = require('path');
    const webpack = require('webpack');
    const CopyWebpackPlugin = require('copy-webpack-plugin');
    const config = require('../../server/config');
    
    module.exports = options => ({
      mode: options.mode,
      entry: options.entry,
      output: Object.assign(
        {
          // Compile into js/build.js
          path: path.resolve(process.cwd(), 'build'),
          publicPath: '/',
        },
        options.output,
      ), // Merge with env dependent settings
      optimization: options.optimization,
      module: {
        rules: [
          {
            test: /\.js$|\.jsx$/, // Transform all .js files required somewhere with Babel
            exclude: /node_modules\/(?!(jqwidgets-scripts\/jqwidgets-react)\/).*/,
            use: {
              loader: 'babel-loader',
              options: options.babelQuery,
            },
          },
          // {
          //   test: /\.js$|\.jsx$/,
          //   exclude: '/node_modules',
          //   include: '/jqwidgets-scripts/jqwidgets-react',
          //   use: {
          //     loader: 'babel-loader',
          //     options: options.babelQuery
          //   }
          // },
          {
            // Preprocess our own .css files
            // This is the place to add your own loaders (e.g. sass/less etc.)
            // for a list of loaders, see https://webpack.js.org/loaders/#styling
            test: /\.scss$/,
            exclude: /node_modules/,
            use: ['style-loader', 'css-loader', 'sass-loader'],
          },
          {
            // Preprocess 3rd party .css files located in node_modules
            test: /\.css$/,
            include: /node_modules/,
            use: ['style-loader', 'css-loader'],
          },
          {
            test: /\.(eot|otf|ttf|woff|woff2)$/,
            use: 'file-loader',
          },
          {
            test: /\.svg$/,
            use: [
              {
                loader: 'svg-url-loader',
                options: {
                  // Inline files smaller than 10 kB
                  limit: 10 * 1024,
                  noquotes: true,
                },
              },
            ],
          },
          {
            test: /\.(jpg|png|gif)$/,
            use: [
              {
                loader: 'url-loader',
                options: {
                  // Inline files smaller than 10 kB
                  limit: 10 * 1024,
                },
              },
              {
                loader: 'image-webpack-loader',
                options: {
                  mozjpeg: {
                    enabled: false,
                    // NOTE: mozjpeg is disabled as it causes errors in some Linux environments
                    // Try enabling it in your environment by switching the config to:
                    // enabled: true,
                    // progressive: true,
                  },
                  gifsicle: {
                    interlaced: false,
                  },
                  optipng: {
                    optimizationLevel: 7,
                  },
                  pngquant: {
                    quality: '65-90',
                    speed: 4,
                  },
                },
              },
            ],
          },
          {
            test: /\.html$/,
            use: 'html-loader',
          },
          {
            test: /\.(mp4|webm)$/,
            use: {
              loader: 'url-loader',
              options: {
                limit: 10000,
              },
            },
          },
        ],
      },
      plugins: options.plugins.concat([
        // Always expose NODE_ENV to webpack, in order to use `process.env.NODE_ENV`
        // inside your code for any environment checks; Terser will automatically
        // drop any unreachable code.
    
        /* new webpack.ProvidePlugin({
          $: 'jquery',
          jQuery: 'jquery',
        }), */
    
        new webpack.DefinePlugin({
          'process.env': {
            NODE_ENV: JSON.stringify(config.env),
            HOST: JSON.stringify(config.server_host),
            PORT: JSON.stringify(config.server_port),
          },
        }),
    
        new webpack.NamedModulesPlugin(),
        new CopyWebpackPlugin([{ from: 'static' }]),
      ]),
      resolve: {
        modules: ['node_modules', 'app'],
        extensions: ['.js', '.jsx', '.react.js'],
        mainFields: ['browser', 'jsnext:main', 'main'],
        alias: {
          moment$: 'moment/moment.js',
        },
      },
      devtool: options.devtool,
      target: 'web', // Make web variables accessible to webpack, e.g. window
      performance: options.performance || {},
    });
    

    这里有一个要排除的正则表达式 node_modules 但包括 jqwidgets-scripts/jqwidgets-react 接下来是一个带有另一种方法的注释块,也没有成功。

    这就是 webpack.prod.babel.js版本 :

    // Important modules this config uses
    const path = require('path');
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    const WebpackPwaManifest = require('webpack-pwa-manifest');
    const OfflinePlugin = require('offline-plugin');
    const { HashedModuleIdsPlugin } = require('webpack');
    const TerserPlugin = require('terser-webpack-plugin');
    const CompressionPlugin = require('compression-webpack-plugin');
    
    module.exports = require('./webpack.base.babel')({
      mode: 'production',
    
      // In production, we skip all hot-reloading stuff
      entry: [
        require.resolve('react-app-polyfill/ie11'),
        path.join(process.cwd(), 'app/app.js'),
      ],
    
      // Utilize long-term caching by adding content hashes (not compilation hashes) to compiled assets
      output: {
        filename: '[name].[chunkhash].js',
        chunkFilename: '[name].[chunkhash].chunk.js',
      },
    
      optimization: {
        minimize: true,
        minimizer: [
          new TerserPlugin({
            terserOptions: {
              warnings: false,
              compress: {
                comparisons: false,
              },
              parse: {},
              mangle: true,
              output: {
                comments: false,
                ascii_only: true,
              },
            },
            parallel: true,
            cache: true,
            sourceMap: true,
          }),
        ],
        nodeEnv: 'production',
        sideEffects: true,
        concatenateModules: true,
        splitChunks: {
          chunks: 'all',
          minSize: 30000,
          minChunks: 1,
          maxAsyncRequests: 5,
          maxInitialRequests: 3,
          name: true,
          cacheGroups: {
            commons: {
              test: /[\\/]node_modules[\\/]/,
              name: 'vendor',
              chunks: 'all',
            },
            main: {
              chunks: 'all',
              minChunks: 2,
              reuseExistingChunk: true,
              enforce: true,
            },
          },
        },
        runtimeChunk: true,
      },
    
      plugins: [
        // Minify and optimize the index.html
        new HtmlWebpackPlugin({
          template: 'app/index.html',
          minify: {
            removeComments: true,
            collapseWhitespace: true,
            removeRedundantAttributes: true,
            useShortDoctype: true,
            removeEmptyAttributes: true,
            removeStyleLinkTypeAttributes: true,
            keepClosingSlash: true,
            minifyJS: true,
            minifyCSS: true,
            minifyURLs: true,
          },
          inject: true,
        }),
    
        // Put it in the end to capture all the HtmlWebpackPlugin's
        // assets manipulations and do leak its manipulations to HtmlWebpackPlugin
        new OfflinePlugin({
          relativePaths: false,
          publicPath: '/',
          appShell: '/',
    
          // No need to cache .htaccess. See http://mxs.is/googmp,
          // this is applied before any match in `caches` section
          excludes: ['.htaccess'],
    
          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)
            additional: ['*.chunk.js'],
          },
    
          // Removes warning for about `additional` section usage
          safeToUseOptionalCaches: true,
        }),
    
        new CompressionPlugin({
          algorithm: 'gzip',
          test: /\.js$|\.css$|\.html$/,
          threshold: 10240,
          minRatio: 0.8,
        }),
    
        new WebpackPwaManifest({
          name: 'React Boilerplate',
          short_name: 'React BP',
          description: 'My React Boilerplate-based project!',
          background_color: '#fafafa',
          theme_color: '#b1624d',
          inject: true,
          ios: true,
          icons: [
            {
              src: path.resolve('app/images/icon-512x512.png'),
              sizes: [72, 96, 128, 144, 192, 384, 512],
            },
            {
              src: path.resolve('app/images/icon-512x512.png'),
              sizes: [120, 152, 167, 180],
              ios: true,
            },
          ],
        }),
    
        new HashedModuleIdsPlugin({
          hashFunction: 'sha256',
          hashDigest: 'hex',
          hashDigestLength: 20,
        }),
      ],
    
      performance: {
        assetFilter: assetFilename =>
          !/(\.map$)|(^(main\.|favicon\.))/.test(assetFilename),
      },
    });
    

    最后我的 babel.config.js :

    module.exports = {
      presets: [
        [
          '@babel/preset-env',
          {
            modules: false,
          },
        ],
        '@babel/preset-react',
      ],
      plugins: [
        'styled-components',
        '@babel/plugin-proposal-export-namespace-from',
        '@babel/plugin-proposal-class-properties',
        '@babel/plugin-syntax-dynamic-import',
      ],
      env: {
        production: {
          only: ['app'],
          plugins: [
            'lodash',
            'transform-react-remove-prop-types',
            '@babel/plugin-transform-react-inline-elements',
            '@babel/plugin-transform-react-constant-elements',
          ],
        },
        test: {
          plugins: [
            '@babel/plugin-transform-modules-commonjs',
            'dynamic-import-node',
          ],
        },
      },
    };
    

    我这里缺什么?我做错什么了吗?我怎样才能在生产中工作?

    1 回复  |  直到 6 年前
        1
  •  1
  •   d7my    6 年前

    我用的是同一个样板 React-Boilerplate@3.7.0 而且效果很好。 因为我看不到你的代码,我认为它与 jqwidgets-scripts 为什么要这样做? 你需要做的是把它从 webpack.config 文件并将其导入到代码库中,如 docs

    import JqxProgressBar from '../../../jqwidgets-react/react_jqxprogressbar.js';
    import JqxButton from '../../../jqwidgets-react/react_jqxbuttons.js';
    import JqxCheckBox from '../../../jqwidgets-react/react_jqxcheckbox.js';
    

    编辑: 所以基于 this 要解决这个问题,您必须更新 webpack.base.babel.js 文件:

    {
         test: /\.js$/,
         exclude: /node_modules/,
         use: {
            loader: 'babel-loader',
              options: options.babelQuery,
         },
    }
    

    在你的代码中你可以开始使用 jqwidgets-react 直接地

    import JqxBarGauge from 'jqwidgets-scripts/jqwidgets-react/react_jqxbargauge.js'