Jump to content

Importing via Webpack gives lots of error TS2300: Duplicate identifier errors


Nikos123
 Share

Recommended Posts

I'm using webpack and want to bundle babylonjs. I'm importing like so:

import BABYLON from 'babylonjs'

And have this webpack config:

var path = require("path");
var webpack = require("webpack");
var HtmlWebpackPlugin = require("html-webpack-plugin");

const PATHS = {
  app: path.join(__dirname, '../client'),
  build: path.join(__dirname, '../server/public')
};

module.exports = {


  entry: {
    app: PATHS.app + '/Game.ts'
  },
  output: {
    path: PATHS.build,
    filename: '[name].js'
  },


  devtool: "source-map",
  module: {
    loaders: [
      {
        test: /\.ts$/,
        loader: 'ts-loader'
      },
      {
        test: /\.pcss$/,
        loaders: [
          'style-loader',
          'css-loader?importLoaders=1',
          'postcss-loader'
        ]
      },
      {
        test: /\.css$/,
        loaders: [
          'style-loader',
          'css-loader'
        ]
      }
    ]



  },
  resolve: {
    // you can now require('file') instead of require('file.js')
    extensions: ['.js', '.json', '.pcss']
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: 'Webpack demo',
      hash: true,
      filename: 'index.html',
      template: PATHS.app + '/index.html',
    })
  ]
};

Same issue with https://github.com/s-panferov/awesome-typescript-loader

Link to comment
Share on other sites

  • 2 weeks later...

Hey @Nikos123, did you find a solution? I am also trying to bundle in ES6 standards for a library I am doing.

 I passed a week trying to bundle Babylon, so let me share the love. (NB. there might be a better way, I am still battling with this)

I don't think there is a cure-all since Babylon bundle is not UMD compatible it can not really be imported using ES6 import. 

To import babylon, either you

  1. Want to use ES6 import ... from and need to webpack bundle a custom version of Babylon using webpack first, you can see my github repo for that : https://github.com/albertbuchard/experiment-babylon-js.git.
    BUT it is a bundle of a bundle, not really recommended, and with Canvas2d 2.5 (my version here) there seems to have some reference issues in terms of getters and setters
  2. OR you use const BABYLON = require('.../babylon.js') on a custom bundle downloaded from the website 

 

Firstoff, I do not think bundling Babylon inside your custom bundle is the way to go, it becomes very large and cannot be updated easilly with new Babylon version (although I tried it also). What I am doing right now is treat babylon as an external, but this is not a piece of cake either...

So first I tried importing Babylon using require(), my webpack config looked like this :

// @flow

// import path from 'path'
import webpack from 'webpack'

const WDS_PORT = 7000

const PROD = JSON.parse(process.env.PROD_ENV || '0')

const libraryName = 'experiment'
const outputFile = `${libraryName}${PROD ? '.min' : '.max'}.js`
const plugins = [
  new webpack.optimize.OccurrenceOrderPlugin(),
]
const prodPlugins = plugins.concat(new webpack.optimize.UglifyJsPlugin())
// not really working
export default {
  entry: './builder.js',
  target: 'web',
  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)/,
      },
    ],

  },
  devtool: PROD ? false : 'source-map',
  resolve: {
    extensions: ['.js', '.jsx'],
  },
  externals: {
    jquery: 'jQuery',
    chartjs: 'Chart',
    lodash: '_',
    'experiment-mathjs': 'math',
    'experiment-boxes': 'experimentBoxes', 
    'experiment-babylon-js/lib/babylon.custom.js': 'BABYLON',
  },
  devServer: {
    port: WDS_PORT,
    hot: true,
  },
  plugins: PROD ? prodPlugins : plugins,
}


I am using a builder.js file as an entry file that simple import and export all my classes, and set some window.globals if we are in the browser environment ..

But it did not work for me, because you need to block babylon to load in node environment, if you want to use server side rendering frameworks especially... After testing and testing again in node.. I realize this does not work without using webpack bundling first on a custom version... That's why I did it in the first place, then bug bugs bugss and I forgot and... Ok so webpack bundling first to protect against BABYLON being exposed in node environment...

(I tried this: http://stackoverflow.com/questions/30246519/webpack-externals-in-both-node-and-the-browser -- did not work)

So in my bundle I used this as the entry point:

builder.js

let BABYLON = {}
let OIMO = {}

if (typeof window !== 'undefined') {
  BABYLON = require('./src/babylon.2.5.full.max')
  OIMO = require('./src/Oimo').OIMO
  window.BABYLON = BABYLON
  window.OIMO = OIMO
}

module.exports = { BABYLON, OIMO }

And a webpack config with externals like so:

{
  externals: {
    jquery: true,
    chartjs: true,
    lodash: true,
    'experiment-mathjs': true,
    'experiment-boxes': true,
    'experiment-babylon-js': true,
  },
}

And using import like so will work...

import _ from 'lodash'
import { BABYLON } from 'experiment-babylon-js'

 

If you want to see the library repo importing all those and trying to bundle you can check : https://github.com/albertbuchard/Experiment.js.git 

But this is still under heavy development.. I mean heavy "trying to bundle this for ages" , so dont expect a perfect solution !

 

Let me know if you found a way :)

@Deltakosh Any plan in the future to implement ES6 / UMD import /export compliance ? I dont know how hard it would be since the code is already extremlly modular in TS it should be a breeze no ?

Link to comment
Share on other sites

4 hours ago, Nikos123 said:

does webpack config with externals just copy the original to the dest?

 

If so , why do you need a custom build? @AlbertTJames

@Nikos123 Treating a library as an external tells webpack not to try and bundle it with your code and tells it the dependency will be available in the code at runtime. It will either be imported in the client javascript file or inside a script tag. 

You have to give it the name of the final reference depending on the style of import (comonjs, global, umd etc..) but this I am not exactly clear how to master. String names seem necessary for require().

 

4 hours ago, Nikos123 said:

Also I'm keen to now what you are doing with babylon on the server side?

I am not doing anything particular per se but the library i am developping is aiming for versatility and ease of use. 

It should perform well on any client wether it be electron, meteor, or other frameworks such as next.js. Some of those have server side rendering and all those need to handle loading dependencies gracefully.

Also one of the class in the framework offers a comon interface with databases/api/file system to store application and event related data. That would benefit from server side implementation.

Currently loading babylon in node generates error even without calling any functions, probably because window or browser function  accessed in the global scope ? (I did not check in detail)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...