edtf.js
edtf.js copied to clipboard
global is not defined
My apologies, but I cannot tell if this is a problem with the configuration of my React application or the packaging of edtf.js.
Using version 4.1.0 and 4.0.0, I get when running the application in a browser:
Uncaught ReferenceError: global is not defined
js date.js:17
However, with 3.1.0 no error is received and edtf.js works as expected.
The webpack config is:
// Copyright 2019 Stanford University see LICENSE for license
/* eslint node/no-unpublished-require: ["off"] */
const path = require("path")
const webpack = require("webpack")
const HtmlWebpackPlugin = require("html-webpack-plugin")
module.exports = {
entry: "./src/index.js",
module: {
noParse: /bad_json/,
rules: [
{
test: /\.(js|jsx)$/,
include: path.resolve(__dirname, "./src"),
exclude: /node_modules/,
use: ["babel-loader"],
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
{
test: /\.(scss)$/,
use: [
{
// inject CSS to page
loader: "style-loader",
},
{
// translates CSS into CommonJS modules
loader: "css-loader",
},
{
// Run postcss actions
loader: "postcss-loader",
options: {
// `postcssOptions` is needed for postcss 8.x;
// if you use postcss 7.x skip the key
postcssOptions: {
// postcss plugins, can be exported to postcss.config.js
plugins() {
return [require("autoprefixer")]
},
},
},
},
{
// compiles Sass to CSS
loader: "sass-loader",
},
],
},
{
test: /\.(png|jpe?g|gif|svg|eot|ttf|woff|woff2)$/i,
// More information here https://webpack.js.org/guides/asset-modules/
type: "asset",
},
],
},
resolve: {
extensions: ["*", ".js", ".jsx"],
fallback: {
fs: false,
stream: require.resolve("stream-browserify"),
crypto: require.resolve("crypto-browserify"),
},
},
output: {
path: path.join(__dirname, "/dist"),
publicPath: "/dist/",
filename: "bundle.js",
},
plugins: [
new webpack.ProvidePlugin({
Buffer: ["buffer", "Buffer"],
process: "process/browser",
}),
new HtmlWebpackPlugin({
template: "index.html",
filename: "index.html",
hash: true,
}),
new webpack.EnvironmentPlugin({
USE_FIXTURES: null,
SINOPIA_API_BASE_URL: null,
SINOPIA_GROUP: null,
SINOPIA_ENV: null,
SINOPIA_URI: null,
AWS_COGNITO_DOMAIN: null,
COGNITO_CLIENT_ID: null,
COGNITO_USER_POOL_ID: null,
INDEX_URL: null,
SEARCH_HOST: null,
EXPORT_BUCKET_URL: null,
HONEYBADGER_API_KEY: null,
HONEYBADGER_REVISION: null,
}),
],
devtool: "source-map",
devServer: {
static: "./dist",
historyApiFallback: true,
hot: true,
port: 8888,
proxy: {
"/api/search": "http://localhost:8000",
},
},
}
Thanks in advance for your assistance.
I would guess it's a packaging problem. We use global to access the global namespace namespace in a couple of places; I'm not using Webpack myself, but I'm sure there is some convention how to convert it (presumably, either renaming global to window or by defining var global = window as a global variable).
My understanding is that webpack is supposed to do that automagically: https://webpack.js.org/guides/ecma-script-modules/
Other ESM modules that the app uses are transpiled correctly, but I don't know if they use global in the same way.
I don't think this is about ESM modules at all. Both browsers and Node.js support ESM nowadays, but this is still an ESM module written for Node.js: it depends on Node.js modules and the Node.js API, where there is a global variable global to access the global namespace; in the Browser window would be the equivalent. When transpiing for use in the browser, you need a solution for this. As this is very common, I suspect Webpack will have a solution for this if enabled in the config; otherwise you should be able to work around it easily by defining global = window yourself before EDTF is loaded.
Did anyone come up with a nice solution to this?
I can't add const global = window about import without my linter screaming.
I haven't been able to add a new plugin which maps global.Date to a safe Date it can use.
Would modifying src/date.js like this work:
const Parent = (typeof window === 'undefined' ? global.Date : window.Date)
export class Date extends Parent {
Is this still about Webpack? In the docs it says that Webpack polyfills global by default so I wonder if this is Webpack issue?
That said, yes, it should be trivial to work around this by temporarily storing the original Date object in an extra variable.
we also ran into this issue. Why not use https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis ? it should work for everyone
webpack5 doesn't provide polyfills for Node by default: https://stackoverflow.com/questions/64557638/how-to-polyfill-node-core-modules-in-webpack-5
Using globalThis should be fine yes.
thanks a lot!