最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Use webpack to bundle several ES6 classes into one file for import in a script tag - Stack Overflow

programmeradmin2浏览0评论

It has been three days now that I am trying to understand webpack to perform a simple task (that of course, in the course of three days I could have done by hand) but for the sake of learning webpack and be able to scale up...

I come with you with a desperate question, that is related probably to what this person was trying to achieve How do I concatenate and minify files using webpack but his solution did not work for me.

The problem is quite simple I have three classes:

./src/class1.js

export default class One {
  constructor() {
    this.isHorrible = true
  }

  whatIsHorrible() {
    return (this)
  }
}

./src/class2.js

class Two {
  iMSoFat() {
    this.fatness = 88
    return (this.fatness)
  }
}

export { Two }

./src/class3.js

class Three {
  constructor() {
    this.isHorrible = true
  }

  whatIsHorrible() {
    return (this)
  }
}

export { Three } 

What i would like to do is in an index.html page :

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Test ton cul</title>
    <script src="./lib/ebjs.js" charset="utf-8"></script>
  </head>
  <body>
    <script type="text/javascript">
      console.log(One, Two, Three);
    </script>
  </body>
</html>

I would also be satisfied with

new window.One() 
//.. or EVEN 
new window.ebjs.One() 

So I tried several config, I will spare you the excrutiating details and frustrations I went through... Lack of sleep and food.

I tried for a long long time to make the array entry point work... but then I read somewhere in the doc "If you pass an array: All modules are loaded upon startup. The last one is exported." And that explained a lot... I always got only one of the class somehow.... whatever that means... why would it behave like that ? It make absolutely no sense to me... anyways... But even then, the class I got was not of the form library.class() or window.class() or class().

So after a while I though, lets load everything in an index.js and export it !

I first tried ES6 import for the style, because why not. But import {One} from './src/class1' does not work somehow, just produce a bunch on undefined export.. Like window.library.One = undefined.

So I fiddled round for a while again before settling for this index.js:

index.js

const class1 = require('./src/class1')
const class2 = require('./src/class2')
const class3 = require('./src/class3')


export { class1, class2, class3 }

My webpack config has changed quite a bit but here is what I am using now :

webpackrc.config.babel.js

const libraryName = 'ebjs'
const outputFile = `${libraryName}.js` 

export default {
  entry: './index.js',
  target: 'web',
  // entry: './index.js',
  devtool: 'source-map',
  output: {
    path: `${__dirname}/lib`,
    filename: outputFile,
    library: libraryName,
    libraryTarget: 'umd',
    umdNamedDefine: true,
  },
  module: {
    loaders: [
      {
        test: /(\.jsx|\.js)$/,
        loader: 'babel-loader',
        exclude: /(node_modules|bower_components)/,
      },
    ],
  },
}

A lot of details and trial/errors have been painfully undertaken.. and I did write a log of my experimentations.. maybe I will share it with the world before pulling the trigger in a couple of hours.

Anyways, it kindof works, but not as expected and definitly not at production quality. To access the class I have to use "new libraryName.One.One()". If I wanted to bundle this for npm this would make no sense for the users. It still does not work as expect.

Here is a screenshot of the object on the page:

I hope someone will come to my aid. My life truly might depend on it :)

Thanks !

EDIT AND END

So cbll answer did work... I could use the es6 import statement and the classes were correctly exported into the bundle. In the html I could use

libraryName.class()

I created a small repo if someone is ever in the same predicament as I was:

Thank you again cbll and Michael Jungo !

It has been three days now that I am trying to understand webpack to perform a simple task (that of course, in the course of three days I could have done by hand) but for the sake of learning webpack and be able to scale up...

I come with you with a desperate question, that is related probably to what this person was trying to achieve How do I concatenate and minify files using webpack but his solution did not work for me.

The problem is quite simple I have three classes:

./src/class1.js

export default class One {
  constructor() {
    this.isHorrible = true
  }

  whatIsHorrible() {
    return (this)
  }
}

./src/class2.js

class Two {
  iMSoFat() {
    this.fatness = 88
    return (this.fatness)
  }
}

export { Two }

./src/class3.js

class Three {
  constructor() {
    this.isHorrible = true
  }

  whatIsHorrible() {
    return (this)
  }
}

export { Three } 

What i would like to do is in an index.html page :

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Test ton cul</title>
    <script src="./lib/ebjs.js" charset="utf-8"></script>
  </head>
  <body>
    <script type="text/javascript">
      console.log(One, Two, Three);
    </script>
  </body>
</html>

I would also be satisfied with

new window.One() 
//.. or EVEN 
new window.ebjs.One() 

So I tried several config, I will spare you the excrutiating details and frustrations I went through... Lack of sleep and food.

I tried for a long long time to make the array entry point work... but then I read somewhere in the doc "If you pass an array: All modules are loaded upon startup. The last one is exported." And that explained a lot... I always got only one of the class somehow.... whatever that means... why would it behave like that ? It make absolutely no sense to me... anyways... But even then, the class I got was not of the form library.class() or window.class() or class().

So after a while I though, lets load everything in an index.js and export it !

I first tried ES6 import for the style, because why not. But import {One} from './src/class1' does not work somehow, just produce a bunch on undefined export.. Like window.library.One = undefined.

So I fiddled round for a while again before settling for this index.js:

index.js

const class1 = require('./src/class1')
const class2 = require('./src/class2')
const class3 = require('./src/class3')


export { class1, class2, class3 }

My webpack config has changed quite a bit but here is what I am using now :

webpackrc.config.babel.js

const libraryName = 'ebjs'
const outputFile = `${libraryName}.js` 

export default {
  entry: './index.js',
  target: 'web',
  // entry: './index.js',
  devtool: 'source-map',
  output: {
    path: `${__dirname}/lib`,
    filename: outputFile,
    library: libraryName,
    libraryTarget: 'umd',
    umdNamedDefine: true,
  },
  module: {
    loaders: [
      {
        test: /(\.jsx|\.js)$/,
        loader: 'babel-loader',
        exclude: /(node_modules|bower_components)/,
      },
    ],
  },
}

A lot of details and trial/errors have been painfully undertaken.. and I did write a log of my experimentations.. maybe I will share it with the world before pulling the trigger in a couple of hours.

Anyways, it kindof works, but not as expected and definitly not at production quality. To access the class I have to use "new libraryName.One.One()". If I wanted to bundle this for npm this would make no sense for the users. It still does not work as expect.

Here is a screenshot of the object on the page:

I hope someone will come to my aid. My life truly might depend on it :)

Thanks !

EDIT AND END

So cbll answer did work... I could use the es6 import statement and the classes were correctly exported into the bundle. In the html I could use

libraryName.class()

I created a small repo if someone is ever in the same predicament as I was:

https://github.com/albertbuchard/example-webpack-es6-class-bundle

Thank you again cbll and Michael Jungo !

Share Improve this question edited May 23, 2017 at 12:17 CommunityBot 11 silver badge asked Mar 10, 2017 at 13:47 Albert James TeddyAlbert James Teddy 1,3751 gold badge13 silver badges25 bronze badges 3
  • 2 Is there any reason you can't define the classes as a var in each file, and just do import Class1 from './class1' in your main js file? I guess you could also just export the class the same way, but I'm not sure this is "proper" ES6 syntax. – cbll Commented Mar 10, 2017 at 13:54
  • I am not sure if I love you or hate you right now... but yeah. That what it ! Me and my sanity are thanking you. For your help you will be made eternal on the GitHub. – Albert James Teddy Commented Mar 10, 2017 at 14:07
  • Cool man, glad to help. I'll add it as an answer, please do accept :-) – cbll Commented Mar 10, 2017 at 14:09
Add a comment  | 

2 Answers 2

Reset to default 8

In each classN.js, export each class by export default One either at the end of the file, of at the beginning(As you do in your "One" example, but not the others). In your index.js, import each by such: import One from './classN.js', of course assuming they are in the same folder(if not, add proper pathing). It will then be included in your main index.js, and bundled with Webpack.

In your case, this means your index.js would start out something like this:

import One from ('./src/class1.js')
import Two from ('./src/class2.js')
import Three from ('./src/class3.js')

This is assuming you export all your classes like One in your example, so:

export default class One { // code goes here

export default class Two { // code goes here

export default class Three { // code goes here

You're pretty much there, but it looks like you're a bit confused by the import/export syntax.

First of all you export the classes differently. In ./src/class1.js you use the default export: export default class One { but in the other two you use named exports export { Two }. To import them correctly you would have:

import One from './src/class1'
import { Two } from './src/class2'
import { Three } from './src/class3'

Because require works differently from ES modules the equivalent with require is:

const One = require('./src/class1').default;
const Two = require('./src/class2').Two;
const Three = require('./src/class3').Three;

Then you can simply export them with:

export { One, Two, Three }

And in your index.html you need to add the library prefix:

<script type="text/javascript">
  console.log(ebjs.One, ebjs.Two, ebjs.Three);
</script>
发布评论

评论列表(0)

  1. 暂无评论