我正在尝试将我在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,
}
我是在正确的轨道上吗?
答案 0 :(得分:0)
好的我的解决方案到目前为止,虽然感觉像是黑客,但在节点环境中防止require()
。
在您的webpack配置的入口文件中检查是否已定义window
。
以下是尝试重新捆绑严重依赖窗口的babylonjs时的示例,并在节点需要时生成错误:
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 }
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:
bundle.test.js
const test = require('./lib/babylon.min.js')
console.log(test)
将在终端产生:
$ node bundle.test.js
{ BABYLON: {}, OIMO: {} }