Thursday, 16 March 2017

Is there a way to protect against bugs when trying to load a webpacked module made for browsers in node.js?

I am trying to upgrade an old framework I built in javascript to es6/module standards and I have a lot of troubles.

One of my current problems is that due to server side rendering my modules are sometime loaded in the node environment and are trying to access the window, causing errors.

Is there a principled way to manage this ?

The main jQuery file has a nice failback if window is undefined and can load in node without a fuss. I am trying to implement this in web-pack by I am stumbling.

This is my current webpack config

// @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: {
    chartjs: {
      commonjs: 'chartjs',
      amd: 'chartjs',
      root: 'Chart', // indicates global variable
    },
    lodash: {
      commonjs: 'lodash',
      amd: 'lodash',
      root: '_', // indicates global variable
    },
    jquery: 'jQuery',
    mathjs: {
      commonjs: 'mathjs',
      amd: 'mathjs',
      root: 'math', // indicates global variable
    },
    'experiment-boxes': {
      commonjs: 'experiment-boxes',
      amd: 'experiment-boxes',
      root: 'experimentBoxes', // indicates global variable
    },
    'experiment-babylon-js': {
      commonjs: 'experiment-babylon-js',
      amd: 'experiment-babylon-js',
      root: 'EBJS', // indicates global variable
    },
  },
  devServer: {
    port: WDS_PORT,
    hot: true,
  },
  plugins: PROD ? prodPlugins : plugins,
}

And this is my main entry point builder.js

/* --- Import the framwork --- */
 import TaskObject from './src/framework/TaskObject'
 import StateManager from './src/framework/StateManager'
 import State from './src/framework/State'
 import EventData from './src/framework/EventData'
 import DataManager from './src/framework/DataManager'
 import RessourceManager from './src/framework/RessourceManager'

 import {
   Array,
   String,
   diag,
   rowSum,
   getRow,
   matrix,
   samplePermutation,
   rep,
   Deferred,
   recurse,
   jitter,
   delay,
   looksLikeAPromise,
   mustHaveConstructor,
   mustBeDefined,
   mandatory,
   debuglog,
   debugWarn,
   debugError,
   noop,
 } from './src/framework/utilities'


/* add it to the global space in case user want to import in a script tag */
 if (typeof window !== 'undefined') {
   window.TaskObject = TaskObject
   window.StateManager = StateManager
   window.State = State
   window.EventData = EventData
   window.DataManager = DataManager
   window.RessourceManager = RessourceManager
   window.jitter = jitter
   window.delay = delay
   window.Deferred = Deferred
 }


 export {
  TaskObject,
  StateManager,
  State,
  EventData,
  DataManager,
  RessourceManager,
  Array,
  String,
  diag,
  rowSum,
  getRow,
  matrix,
  samplePermutation,
  rep,
  Deferred,
  recurse,
  jitter,
  delay,
  looksLikeAPromise,
  mustHaveConstructor,
  mustBeDefined,
  mandatory,
  debuglog,
  debugWarn,
  debugError,
  noop,
}

Am I on the right track?



via Albert James Teddy

No comments:

Post a Comment