swiper: Webpack Production Bundling fails because of UglifyJS Error with Dom7

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

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 2
  • Comments: 36 (11 by maintainers)

Most upvoted comments

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';

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.

I did like this… It also works!

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

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

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.

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

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';

@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.

https://github.com/nolimits4web/swiper/issues/2263#issuecomment-351930175

https://github.com/nolimits4web/swiper/issues/2263#issuecomment-373715451

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

“I’ve downgraded to v3.4.2 and the problem went away.” https://github.com/JeffreyWay/laravel-mix/issues/1244