如何使为浏览器设计的javascript网页包模块在节点环境中安全加载?

如何使为浏览器设计的javascript网页包模块在节点环境中安全加载?,javascript,node.js,webpack,Javascript,Node.js,Webpack,我正在尝试将我在javascript中构建的旧框架升级到es6/模块标准,我遇到了很多麻烦 我当前的一个问题是,由于服务器端渲染,我的模块有时会加载到节点环境中,并试图访问窗口,从而导致错误 有没有一个有原则的方法来管理这个问题 如果窗口未定义,主jQuery文件有一个很好的回切功能,并且可以在节点中加载而不引起任何麻烦。我试图在WebPack中实现这一点,因为我遇到了障碍 这是我当前的网页配置 // @flow // import path from 'path' import webpac

我正在尝试将我在javascript中构建的旧框架升级到es6/模块标准,我遇到了很多麻烦

我当前的一个问题是,由于服务器端渲染,我的模块有时会加载到节点环境中,并试图访问窗口,从而导致错误

有没有一个有原则的方法来管理这个问题

如果窗口未定义,主jQuery文件有一个很好的回切功能,并且可以在节点中加载而不引起任何麻烦。我试图在WebPack中实现这一点,因为我遇到了障碍

这是我当前的网页配置

// @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,
}
这是我的主要入口点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,
}
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 }

我走对了吗?

到目前为止,我的解决方案虽然感觉像是黑客攻击,但可以在节点环境中防止
require()

在网页包配置的输入文件中,检查是否定义了
窗口

以下是尝试重新绑定JS时的一个示例,它严重依赖于窗口,并且在节点需要时会生成错误:

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,
}
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 }
webpack.config.babel.js

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

const WDS_PORT = 7000

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

const plugins = [
  new webpack.optimize.OccurrenceOrderPlugin(),
]
const prodPlugins = plugins.concat(new webpack.optimize.UglifyJsPlugin())

export default {
  entry: [
    './builder.js',
  ],
  output: {
    filename: PROD ? 'babylon.min.js' : 'babylon.max.js',
    path: path.resolve(__dirname, 'lib/'),
    publicPath: `http://localhost:${WDS_PORT}/lib/`,
    library: 'EBJS',
    libraryTarget: 'umd',
    umdNamedDefine: true,
  },
  module: {
    rules: [
      { test: /\.(js|jsx)$/, use: 'babel-loader', exclude: /node_modules/ },
    ],
  },
  devtool: PROD ? false : 'source-map',
  resolve: {
    extensions: ['.js', '.jsx'],
  },
  devServer: {
    port: WDS_PORT,
    hot: true,
  },
  plugins: PROD ? prodPlugins : plugins,
}
使用以下简单文件在节点中测试捆绑包:

bundle.test.js

const test = require('./lib/babylon.min.js')

console.log(test)
将在航站楼生产:

$ node bundle.test.js 
{ BABYLON: {}, OIMO: {} }

好的,到目前为止,我的解决方案虽然感觉像是黑客攻击,但可以在节点环境中防止
require()

在网页包配置的输入文件中,检查是否定义了
窗口

以下是尝试重新绑定JS时的一个示例,它严重依赖于窗口,并且在节点需要时会生成错误:

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,
}
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 }
webpack.config.babel.js

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

const WDS_PORT = 7000

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

const plugins = [
  new webpack.optimize.OccurrenceOrderPlugin(),
]
const prodPlugins = plugins.concat(new webpack.optimize.UglifyJsPlugin())

export default {
  entry: [
    './builder.js',
  ],
  output: {
    filename: PROD ? 'babylon.min.js' : 'babylon.max.js',
    path: path.resolve(__dirname, 'lib/'),
    publicPath: `http://localhost:${WDS_PORT}/lib/`,
    library: 'EBJS',
    libraryTarget: 'umd',
    umdNamedDefine: true,
  },
  module: {
    rules: [
      { test: /\.(js|jsx)$/, use: 'babel-loader', exclude: /node_modules/ },
    ],
  },
  devtool: PROD ? false : 'source-map',
  resolve: {
    extensions: ['.js', '.jsx'],
  },
  devServer: {
    port: WDS_PORT,
    hot: true,
  },
  plugins: PROD ? prodPlugins : plugins,
}
使用以下简单文件在节点中测试捆绑包:

bundle.test.js

const test = require('./lib/babylon.min.js')

console.log(test)
将在航站楼生产:

$ node bundle.test.js 
{ BABYLON: {}, OIMO: {} }

使用巴别塔。使用es6标准编写项目,然后使用babel导出符合web的项目。使用babel。使用es6标准编写项目,然后使用babel导出符合web的项目。