Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Webpack Production Bundling fails because of UglifyJS Error with Dom7 #2263

Closed
martinherweg opened this issue Oct 18, 2017 · 36 comments

Comments

@martinherweg
Copy link

commented Oct 18, 2017

This is a (multiple allowed):

  • bug

  • enhancement

  • feature-discussion (RFC)

  • Swiper Version: 4.0.1.

  • Platform/Target and Browser Versions: -

What you did

I have installed Swiper as normal dependency in my Project and import it to my scripts file like this import Swiper from 'swiper';
If I try to bundle it to a production ready version with webpack i get this error

Unexpected token: name (Dom7) [./node_modules/dom7/dist/dom7.modular.js:14,0][js/vendor.a8b881e4dc98829fb5c4.js:36577,6]

ERROR in js/vendor.a8b881e4dc98829fb5c4.js from UglifyJs
Unexpected token: name (Dom7) [./node_modules/dom7/dist/dom7.modular.js:14,0][js/vendor.a8b881e4dc98829fb5c4.js:36577,6]

as soon as I downgrade Swiper to version 3.4.2 everything works as expected.

Expected Behavior

Bundling and compression via webpack is working

Actual Behavior

UglifyJS throws an error because of dom7

@nolimits4web

This comment has been minimized.

Copy link
Owner

commented Oct 18, 2017

Make sure you have enabled Bable or Buble for Swiper ES-module to transpile it from ES-next syntax

@martinherweg

This comment has been minimized.

Copy link
Author

commented Oct 20, 2017

@nolimits4web I use ES6 syntax in my own code and use babel-loader to compile.
I use babel-preset-env in my .babelrc but it's still not working.

@nusson

This comment has been minimized.

Copy link

commented Oct 25, 2017

"I've downgraded to v3.4.2 and the problem went away."
JeffreyWay/laravel-mix#1244

@daviddelusenet

This comment has been minimized.

Copy link

commented Oct 26, 2017

@nolimits4web can you share a working webpack config?

@daviddelusenet

This comment has been minimized.

Copy link

commented Oct 27, 2017

I fixed this by removing the following line: exclude: /node_modules/, from my Webpack config.

@nolimits4web distributing Swiper as an ES6 module is wrong in my eyes. Now during compilation Webpack has to search through my entire node_modules folder to look for ES6 modules which can become really slow.

Can you please provide an ES5 version of Swiper?

@nolimits4web

This comment has been minimized.

Copy link
Owner

commented Oct 27, 2017

Well, there is probably kind of option to look only in node_modules/swiper. The reason why i keep it in ES6 is the tree-shaking. It just doesn't work properly with ES5-syntax modules.

You may then just include UMD version of swiper which is in ES5: import Swiper from 'swiper/dist/js/swiper.js';

@martinherweg

This comment has been minimized.

Copy link
Author

commented Oct 27, 2017

Maybe we can use the include option in loaders to just include swiper.

@nolimits4web How do you do it in Projects where you need to compile everything down to ES5?

@nolimits4web

This comment has been minimized.

Copy link
Owner

commented Oct 27, 2017

I don't say it should not be compiled to ES5, it must be. The bundle package must be compiled. But keeping Swiper module is in ES6 syntax is a mandatory for tree-shaking to work. For example, if it is in ES5 syntax then:

import { Swiper, Pagination } from 'swiper/dist/js/swiper.esm.js';

Will still keep all other modules you don't need in your bundle

@deasmahaputra

This comment has been minimized.

Copy link

commented Oct 27, 2017

@daviddelusenet

This comment has been minimized.

Copy link

commented Oct 27, 2017

Ok guys I managed to fix it. Just use the normal Swiper import method:

import Swiper from 'swiper';

Then in your Webpack config add the following part:

module: {
  rules: [
    {
      test: /\.js$/, // Check for all js files
      exclude: /node_modules\/(?!(dom7|swiper)\/).*/,
      loader: 'babel-loader'
    }
  ]
}

This excludes all node_modules from your babel-loader but includes dom7 and swiper.

@DanielRuf

This comment has been minimized.

Copy link
Contributor

commented Dec 8, 2017

#2263 (comment)

Unfortunately it seems this is not enough. What is your babel-preset that you use and do you have a .babelrc and what are its contents?

Upgrading UglifyJS to version 3 solved it for us.

@daviddelusenet

This comment has been minimized.

Copy link

commented Dec 8, 2017

@DanielRuf I'm using the following Babel configuration

{
  "presets": [
    ["env", {
      "modules": false, // webpack understands the native import syntax and uses it for tree shaking
      "targets": {
        "browsers": ["last 5 versions", "safari >= 7"]
      },
    }],
    "react" // transpile React components to JavaScript
  ],
  "plugins": ["transform-class-properties"],
  "env": {
    "dev": {
      "plugins": [
        "react-hot-loader/babel", // enables React code to work with HMR
        ["react-css-modules", {
          "context": "./src",
          "generateScopedName": "[local]___[hash:base64:5]",
          "filetypes": {
            ".scss": {
              "syntax": "postcss-scss"
            }
          }
        }]
      ]
    },
    "prod": {
      "plugins": [
        ["react-css-modules", {
          "context": "./src",
          "generateScopedName": "[local]___[hash:base64]",
          "filetypes": {
            ".scss": {
              "syntax": "postcss-scss"
            }
          }
        }]
      ]
    }
  }
}
@DanielRuf

This comment has been minimized.

Copy link
Contributor

commented Dec 8, 2017

Hm, does not work here =/ I guess UglifyJS 3 (with uglify-es) used in gulp-uglify with compose and webpack-stream and a .babelrc has some bug as the compressed code still contains template literals and other ES6 features.

@xx4159

This comment has been minimized.

Copy link

commented Dec 15, 2017

I did like this...
It also works!

import * as Swiper from 'swiper/dist/js/swiper.js';
...
... new Swiper(swiperContainer, this.options) ...
...
@DanielRuf

This comment has been minimized.

Copy link
Contributor

commented Dec 15, 2017

Well, this is the compiled dist file and not the esm version or the source version ;-)

@Giovanni-Mattucci

This comment has been minimized.

Copy link

commented Feb 6, 2018

@xx4159 I used your method as I'm using typescript, and it worked for me :)
Better than scanning for Dom7 and Swiper in my node_modules folder.
I couldn't use a regex like this exclude: /node_modules\/(?!(dom7|swiper)\/).*/ in my tsconfig.json.

@charlespernet

This comment has been minimized.

Copy link

commented Feb 23, 2018

Hey guys just sharing my experience here, I am new to WebPack with rails and i spent time struggling to figure out where to add config shared by daviddelusenet.

I you have a classic Rails 5.1 config you should probably have a config/webpacker.yml file.
This file is loaded by config/webpack/environment.js which should look like :

const { environment } = require('@rails/webpacker');
module.exports = environment;

In case you want to add config, just add a file in webpack folder, in my case I added swiper_config.js with this code :

module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/, // Check for all js files
        exclude: /node_modules\/(?!(dom7|swiper)\/).*/,
        loader: 'babel-loader'
      }
    ]
  }
};

then you have to edit your environment.js or production.js (if you want this config only for production) to look like this :

const { environment } = require('@rails/webpacker');
const swiperConfig = require('./swiper_config');

environment.config.merge(swiperConfig);

module.exports = environment;

Hope this could help some newbies like me starting with Webpack.
By the way Swiper is fantastic ! Thanks to people contributing, and special thanks to @daviddelusenet for sharing his solution.

@wujunchuan

This comment has been minimized.

Copy link

commented Mar 16, 2018

to sum up:

Swiper4.x module is in ES6 syntax in order for tree-shaking to work.
Due to my environment is not include babel translater
use UMD version of swiper which is in ES5 work for me:
import Swiper from 'swiper/dist/js/swiper.js';

@oakland oakland referenced this issue Apr 2, 2018

Open

swiper #71

@maximelebreton

This comment has been minimized.

Copy link

commented Oct 1, 2018

Can somebody could provide a .babelrc config version (i'm using Parcel)?

Thanks!

@zebapy

This comment has been minimized.

Copy link

commented Oct 23, 2018

#2263 (comment)

#2263 (comment)

These are not solutions to the problem.

module.exports = {
  exclude: /node_modules\/(?!(dom7|swiper)\/).*/,
  presets: ['@babel/preset-env'],
  plugins: [
    ['@babel/transform-react-jsx', { pragma: 'h' }],
    '@babel/plugin-proposal-class-properties'
  ]
};

is doing nothing for me either. I'm using rollup + gulp.

If I set the exclude: '' then it throws a jsx compile error??...

If I remove exclude it throws the same dom7 error

class Dom7 {
        |        ^ Unexpected token: name (Dom7)
  10057 |     constructor(arr) {
  10058 |       const self = this; // Create array-like object
@daviddelusenet

This comment has been minimized.

Copy link

commented Oct 24, 2018

.babelrc:

{
  "presets": [
    ["@babel/preset-env", {
      "useBuiltIns": "usage",
      "targets": {
        "browsers": [
          "> 5%",
          "last 2 versions",
          "not ie < 11",
          "ios_saf >= 10.2"
        ]
      }
    }],
    "@babel/preset-react"
  ],
  "plugins": ["transform-class-properties"],
  "env": {
    "dev": {
      "plugins": ["babel-plugin-styled-components", "react-hot-loader/babel"]
    }
  }
}

webpack.base.js:

  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules\/(?!(dom7|ssr-window|swiper)\/).*/,
        use: 'babel-loader',
      },`
      // Some more loaders here..
    ],
  },
@zhangliqq

This comment has been minimized.

Copy link

commented Oct 25, 2018

2 n 9 0 05jxx u vz gw_q
glt3b guj6rc7 woe ybknp

These are not solutions to the problem.
I don't sure the problem is from swiper and it occurred only when I build my project. The problem is .call() con't resolve.....sorry it's difficult to describe it.
cx a y bw w6g ok jc f_q

@modestotech

This comment has been minimized.

Copy link

commented Nov 28, 2018

I've had swiper working for many months with the following setup, but now I get the Dom7 unexpected token error, mentiod above. The error is only in IE11, works good in Chrome.

webpack.config.json

module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules\/(?!(dom7|ssr-window|swiper)\/).*/,
        use: 'babel-loader',
      },
      {
// more loaders
}

.babelrc

{
  "presets": ["@babel/preset-env", "@babel/preset-react"],
  "plugins": [
    "@babel/plugin-proposal-class-properties"
  ]
}

Now for some reason it stopped working. Does anyone know of something that has changed in the last months and that may have caused this? That would save some time for me not having to pinpoint the problem. Few people are using IE so it takes some time before the alarm arises.

@DanielRuf

This comment has been minimized.

Copy link
Contributor

commented Nov 28, 2018

Now for some reason it stopped working. Does anyone know of something that has changed in the last months and that may have caused this?

Can you check the node_modules directory for dom7 references?

@modestotech

This comment has been minimized.

Copy link

commented Nov 28, 2018

When I run ll | grep dom7 in node_modules I get one folder named dom7.
Was that what you requested, @DanielRuf ?

@DanielRuf

This comment has been minimized.

Copy link
Contributor

commented Nov 28, 2018

When I run ll | grep dom7 in node_modules I get one folder named dom7.
Was that what you requested, @DanielRuf ?

Was any dependency updated like webpack or babel-loader or swiper itself? In general it should be locked using yarn.lock / package-lock.json to get reproducible builds.

@modestotech

This comment has been minimized.

Copy link

commented Nov 28, 2018

Here is the dependencies for the working version:

  "dependencies": {
    "axios": "^0.18.0",
    "babel-polyfill": "^6.26.0",
    "firebase": "^5.5.4",
    "moment": "^2.22.2",
    "path": "^0.12.7",
    "prop-types": "^15.6.2",
    "react": "^16.5.2",
    "react-datepicker": "^1.6.0",
    "react-dom": "^16.5.2",
    "react-hot-loader": "^3.0.0-beta.1",
    "react-redux": "^5.0.2",
    "react-router": "^4.3.1",
    "react-router-dom": "^4.3.1",
    "redux": "^3.6.0",
    "redux-thunk": "^2.3.0",
    "swiper": "^4.4.1"
  },
  "devDependencies": {
    "babel-core": "^6.26.3",
    "babel-loader": "^7.1.5",
    "babel-preset-env": "^1.7.0",
    "babel-preset-react": "^6.24.1",
    "copy-webpack-plugin": "^4.5.3",
    "cpr": "^3.0.1",
    "css-loader": "^0.28.11",
    "extract-loader": "^2.0.1",
    "extract-text-webpack-plugin": "^4.0.0-beta.0",
    "html-webpack-plugin": "^3.2.0",
    "html-webpack-prefix-plugin": "^1.1.0",
    "node-sass": "^4.8.3",
    "redux-immutable-state-invariant": "^1.2.4",
    "rimraf": "^2.6.2",
    "sass-loader": "^7.1.0",
    "style-loader": "^0.20.3",
    "webpack": "^4.20.2",
    "webpack-cli": "^3.1.2",
    "webpack-dev-server": "^3.1.9",
    "webpack-merge": "^4.1.4",
    "workbox-webpack-plugin": "^3.6.2",
    "write-file-webpack-plugin": "^4.4.1"
  }

Here are the dependencies for the version which is not working, quite some updates done as you can tell.

 "dependencies": {
    "@babel/polyfill": "^7.0.0",
    "axios": "^0.18.0",
    "firebase": "^5.5.4",
    "moment": "^2.22.2",
    "path": "^0.12.7",
    "prop-types": "^15.6.2",
    "react": "^16.5.2",
    "react-datepicker": "^1.8.0",
    "react-dom": "^16.5.2",
    "react-hot-loader": "^4.3.12",
    "react-redux": "^5.0.2",
    "react-router": "^4.3.1",
    "react-router-dom": "^4.3.1",
    "redux": "^4.0.1",
    "redux-thunk": "^2.3.0",
    "swiper": "^4.4.1"
  },
  "devDependencies": {
    "@babel/core": "^7.1.5",
    "@babel/plugin-proposal-class-properties": "^7.1.0",
    "@babel/preset-env": "^7.1.5",
    "@babel/preset-react": "^7.0.0",
    "babel-loader": "^8.0.4",
    "copy-webpack-plugin": "^4.5.3",
    "cpr": "^3.0.1",
    "css-loader": "^1.0.1",
    "eslint": "^5.8.0",
    "eslint-config-airbnb": "^17.1.0",
    "eslint-plugin-import": "^2.14.0",
    "eslint-plugin-jsx-a11y": "^6.1.2",
    "eslint-plugin-react": "^7.11.1",
    "extract-loader": "^3.0.0",
    "extract-text-webpack-plugin": "^4.0.0-beta.0",
    "html-webpack-plugin": "^3.2.0",
    "html-webpack-prefix-plugin": "^1.1.0",
    "node-sass": "^4.8.3",
    "redux-immutable-state-invariant": "^2.1.0",
    "rimraf": "^2.6.2",
    "sass-loader": "^7.1.0",
    "style-loader": "^0.23.1",
    "webpack": "^4.20.2",
    "webpack-cli": "^3.1.2",
    "webpack-dev-server": "^3.1.9",
    "webpack-merge": "^4.1.4",
    "workbox-webpack-plugin": "^3.6.2",
    "write-file-webpack-plugin": "^4.4.1"
  }
```

Babel itself and babel-loader has been updated, among other stuff. Any idea?
@DanielRuf

This comment has been minimized.

Copy link
Contributor

commented Nov 28, 2018

Probably do selective updates and do some bisecting which dependency produces this issue (I guess babel-loader).

@DanielRuf

This comment has been minimized.

Copy link
Contributor

commented Nov 28, 2018

yarn / yarn.lock is often better.

@ViieeS

This comment has been minimized.

Copy link

commented Jan 15, 2019

why just don't include?

rules: [{
    include: [
    path.resolve(__dirname, 'src'),
    /node_modules\/(dom7|swiper)/
  ],
  loader: 'babel-loader',
  presets: [['@babel/preset-env', {
  'modules': false
  }]]
},
  test: /\.(js)$/
}] 
@ViieeS

This comment has been minimized.

Copy link

commented Jan 18, 2019

Looks like TerserPlugin doesn't have such problem. So you don't need to include dom7|swiper in your config.

@bsudeep

This comment has been minimized.

Copy link

commented Jan 22, 2019

Looks like TerserPlugin doesn't have such problem. @ViieeS

Thank you!

@vertic4l

This comment has been minimized.

Copy link

commented Feb 8, 2019

@ViieeS How is this possible? Still got issues with IE11, although latest webpack + TypeScript is being used (no babel-loader). Any ideas (without babel-loader...)?

import { Swiper, Virtual, SwiperOptions, SelectableElement } from "swiper/dist/js/swiper.esm.js";

syntax error:
upload
_node_modules_swiper_dist_js_swiper.esm.js.42a0d73a.73c6129a00ae84c4b9bf.js (11,1)

This is a dev build... but same occurs in prod build. But it's the only npm package with such an error.
Although tons of other npm packages are loaded the same way... and are also ES6 modules.

@DanielRuf

This comment has been minimized.

Copy link
Contributor

commented Feb 8, 2019

Any ideas (without babel-loader...)?

You have to transpile it for browsers.

@vertic4l

This comment has been minimized.

Copy link

commented Feb 8, 2019

@DanielRuf

tsconfig looks like this (and builds for browsers since 2 years...):

"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"target": "es5",
"lib": [
    "es2015",
    "dom",
    "es2017"
],

?

@slorber

This comment has been minimized.

Copy link

commented Jul 18, 2019

@nolimits4web I understand that:

  • you want treeshaking to work for ES users
  • according to the readme, user is responsible for handling the lib transpiling if he wants to consume ES modules and support older browsers (IE11/Edge)

But:

  • You can keep treeshaking and yet transpiling the lib in advance
  • You don't need to ask user to setup transpiling
  • This package is only for the web, so not transpiling is just annoyance for all webpack consumers with no advantage

Let's take a popular package, like Redux.

https://unpkg.com/redux@4.0.4/es/redux.js

You can see in the original source code a modern syntax with const/let/rest/spread and ES6 modules. Yet in the published ES module, you can see an older syntax, but still ES6 modules.

This package works with treeshaking, and does not require webpack users to add any additional config.

Wouldn't it be better if all those issues about uglify / ie / edge failing were not opened because consuming your libs would be easier? Most web users expect to not have to transpile node_modules when installing a lib, and will likely not even read your readme entirely.

Repository owner locked as off topic and limited conversation to collaborators Jul 18, 2019

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
You can’t perform that action at this time.