Webpack, (npm) binding, and require(`fs`) not working together - javascript

Currently working on an SPA that is used to submit user information to a SQL database via an odbc INSERT statement, but my local environment is not being properly constructed and I cant figure out why.
Link to npm's binding: https://www.npmjs.com/package/bindings
macOS
version 10.12.6
node -v
v8.8.1
webpack -v
3.8.1
As of right now, I can use node post.js to successfully make a post to my database. However, when I run grunt build I receive the following errors:
WARNING in ./node_modules/bindings/bindings.js
81:22-40 Critical dependency: the request of a dependency is an expression
WARNING in ./node_modules/bindings/bindings.js
81:43-53 Critical dependency: the request of a dependency is an expression
ERROR in ./node_modules/bindings/bindings.js
Module not found: Error: Can't resolve 'fs' in '/Users/pat/to/project/node_modules/bindings'
# ./node_modules/bindings/bindings.js 6:11-24
# ./node_modules/odbc/lib/odbc.js
# ./assets/scripts/index.js
# ./index.js
Warning: Use --force to continue.
Aborted due to warnings.
Note: I receive the same issue whenever I require fs in any file (the same error occurs for whichever file I require fs in). The require of fs in binding.js is the last instance of the problem because when I remove it from binding.js the code breaks.
So when I take a look at the binding.js file that is being mentioned above, we can see the following (the require(fs) is the important line to look at):
/**
* Module dependencies.
*/
var fs = require('fs')
, path = require('path')
, join = path.join
, dirname = path.dirname
, exists = ((fs.accessSync && function (path) { try { fs.accessSync(path); } catch (e) { return false; } return true; })
|| fs.existsSync || path.existsSync)
, defaults = {
arrow: process.env.NODE_BINDINGS_ARROW || ' → '
, compiled: process.env.NODE_BINDINGS_COMPILED_DIR || 'compiled'
, platform: process.platform
, arch: process.arch
, version: process.versions.node
, bindings: 'bindings.node'
, try: [
// node-gyp's linked version in the "build" dir
[ 'module_root', 'build', 'bindings' ]
// node-waf and gyp_addon (a.k.a node-gyp)
, [ 'module_root', 'build', 'Debug', 'bindings' ]
, [ 'module_root', 'build', 'Release', 'bindings' ]
// Debug files, for development (legacy behavior, remove for node v0.9)
, [ 'module_root', 'out', 'Debug', 'bindings' ]
, [ 'module_root', 'Debug', 'bindings' ]
// Release files, but manually compiled (legacy behavior, remove for node v0.9)
, [ 'module_root', 'out', 'Release', 'bindings' ]
, [ 'module_root', 'Release', 'bindings' ]
// Legacy from node-waf, node <= 0.4.x
, [ 'module_root', 'build', 'default', 'bindings' ]
// Production "Release" buildtype binary (meh...)
, [ 'module_root', 'compiled', 'version', 'platform', 'arch', 'bindings' ]
]
}
/**
* The main `bindings()` function loads the compiled bindings for a given module.
* It uses V8's Error API to determine the parent filename that this function is
* being invoked from, which is then used to find the root directory.
*/
function bindings (opts) {
// Argument surgery
if (typeof opts == 'string') {
opts = { bindings: opts }
} else if (!opts) {
opts = {}
}
// maps `defaults` onto `opts` object
Object.keys(defaults).map(function(i) {
if (!(i in opts)) opts[i] = defaults[i];
});
// Get the module root
if (!opts.module_root) {
opts.module_root = exports.getRoot(exports.getFileName())
}
// Ensure the given bindings name ends with .node
if (path.extname(opts.bindings) != '.node') {
opts.bindings += '.node'
}
var tries = []
, i = 0
, l = opts.try.length
, n
, b
, err
for (; i<l; i++) {
n = join.apply(null, opts.try[i].map(function (p) {
return opts[p] || p
}))
tries.push(n)
try {
b = opts.path ? require.resolve(n) : require(n)
if (!opts.path) {
b.path = n
}
return b
} catch (e) {
if (!/not find/i.test(e.message)) {
throw e
}
}
}
err = new Error('Could not locate the bindings file. Tried:\n'
+ tries.map(function (a) { return opts.arrow + a }).join('\n'))
err.tries = tries
throw err
}
module.exports = exports = bindings
/**
* Gets the filename of the JavaScript file that invokes this function.
* Used to help find the root directory of a module.
* Optionally accepts an filename argument to skip when searching for the invoking filename
*/
exports.getFileName = function getFileName (calling_file) {
var origPST = Error.prepareStackTrace
, origSTL = Error.stackTraceLimit
, dummy = {}
, fileName
Error.stackTraceLimit = 10
Error.prepareStackTrace = function (e, st) {
for (var i=0, l=st.length; i<l; i++) {
fileName = st[i].getFileName()
if (fileName !== __filename) {
if (calling_file) {
if (fileName !== calling_file) {
return
}
} else {
return
}
}
}
}
// run the 'prepareStackTrace' function above
Error.captureStackTrace(dummy)
dummy.stack
// cleanup
Error.prepareStackTrace = origPST
Error.stackTraceLimit = origSTL
return fileName
}
/**
* Gets the root directory of a module, given an arbitrary filename
* somewhere in the module tree. The "root directory" is the directory
* containing the `package.json` file.
*
* In: /home/nate/node-native-module/lib/index.js
* Out: /home/nate/node-native-module
*/
exports.getRoot = function getRoot (file) {
var dir = dirname(file)
, prev
while (true) {
if (dir === '.') {
// Avoids an infinite loop in rare cases, like the REPL
dir = process.cwd()
}
if (exists(join(dir, 'package.json')) || exists(join(dir, 'node_modules'))) {
// Found the 'package.json' file or 'node_modules' dir; we're done
return dir
}
if (prev === dir) {
// Got to the top
throw new Error('Could not find module root given file: "' + file
+ '". Do you have a `package.json` file? ')
}
// Try the parent dir next
prev = dir
dir = join(dir, '..')
}
}
So it appears that requiring fs in the at the top of the code block is causing the issue. If I remove the fs require and run grunt build again, I get the following warnings but no errors:
WARNING in ./node_modules/bindings/bindings.js
81:22-40 Critical dependency: the request of a dependency is an expression
WARNING in ./node_modules/bindings/bindings.js
81:43-53 Critical dependency: the request of a dependency is an expression
I receive the same warnings when running 'grunt serve' but no error. Then when I visit the page on localhost, I'm receiving the following error:
bindings.js:10 Uncaught ReferenceError: fs is not defined
at Object.<anonymous> (bindings.js:10)
at Object.Array.concat.splitPathRe (bindings.js:171)
at __webpack_require__ (bootstrap 2037e18d07470b1345e0:54)
at Object.<anonymous> (odbc.js:18)
at Object.Array.concat.webpackEmptyContext.keys (odbc.js:820)
at __webpack_require__ (bootstrap 2037e18d07470b1345e0:54)
at Object.<anonymous> (index.js:7)
at Object.<anonymous> (application.js:984)
at __webpack_require__ (bootstrap 2037e18d07470b1345e0:54)
at Object.<anonymous> (index.js:8)
So removing the fs require is allowing me to build, but then binding.js is not functioning properly because I removed the fs require. In addition, after removing the fs require in binding.js, I cannot use node to make posts to the database because I removed the fs require in binding.js (receive the error message above).
I've tried debugging by adding the following code to my 'grunt/webpack.js' file as suggested in several posts:
target: 'node',
node: {
fs: 'empty'
}
Link to post that advice is from: https://github.com/webpack-contrib/css-loader/issues/447
Here is my whole 'grunt/webpack.js' file (want to ensure I placed it in the correct location):
'use strict'
const webpack = require('webpack')
const path = require('path')
module.exports = {
options: {
entry: {
application: './index.js',
specs: './spec/_all.js',
vendor: ['jquery', 'bootstrap-sass']
},
output: {
filename: '[name].js',
path: path.join(__dirname, '/../public'),
publicPath: 'public/'
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: Infinity
}),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery'
})
],
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader',
query: {
presets: ['es2015']
}
},
{
test: /\.css$/,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader' }
]
},
{
test: /\.scss$/,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader' },
{
loader: 'sass-loader',
options: {
includePaths: [
path.resolve(__dirname, './node_modules')
]
}
}
]
},
{
test: /\.woff[\d]?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'url-loader?limit=10000&mimetype=application/font-woff'
},
{
test: /\.(ttf|eot|svg|png|jpg|gif)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'file-loader'
},
{
test: /\.(hbs|handlebars)$/,
loader: 'handlebars-loader',
query: {
helperDirs: [
path.join(__dirname, '/../assets/scripts/templates/helpers')
]
}
}
]
},
resolve: {
alias: {
handlebars: 'handlebars/dist/handlebars.js'
}
},
stats: {
colors: true,
modules: true,
reasons: true
}
},
target: 'node',
node: {
fs: 'empty',
console: 'empty',
net: 'empty',
tls: 'empty'
},
build: {
failOnError: true,
watch: false,
keepalive: false
}
}
Here is my package.json as reference for all other relevant installs:
{
"name": "omnipodeurope",
"version": "0.0.3",
"private": true,
"license": {
"software": "GNU GPLv3",
"content": "CC­BY­NC­SA 4.0"
},
"dependencies": {
"bindings": "^1.3.0",
"fs": "0.0.1-security",
"jquery": "^3.2.1",
"odbc": "^1.3.0",
"videojs": "^1.0.0"
},
"devDependencies": {
"babel-core": "^6.25.0",
"babel-loader": "^7.1.1",
"babel-preset-es2015": "^6.24.1",
"bootstrap-sass": "^3.3.7",
"chai": "^4.1.1",
"clone": "^2.1.1",
"css-loader": "^0.27.0",
"eslint": "^4.4.1",
"eslint-config-standard": "^10.2.1",
"eslint-plugin-import": "^2.7.0",
"eslint-plugin-node": "^5.1.1",
"eslint-plugin-promise": "^3.5.0",
"eslint-plugin-standard": "^3.0.1",
"expose-loader": "^0.7.3",
"file-loader": "^1.0.0",
"grunt": "^1.0.1",
"grunt-concurrent": "^2.3.1",
"grunt-eslint": "^20.0.0",
"grunt-jsonlint": "^1.1.0",
"grunt-mocha-phantomjs": "^4.0.0",
"grunt-nodemon": "^0.4.2",
"grunt-open": "^0.2.3",
"grunt-sass-lint": "^0.2.2",
"grunt-shell": "^2.1.0",
"grunt-webpack": "^3.0.2",
"handlebars": "^4.0.10",
"handlebars-loader": "^1.5.0",
"html-loader": "^0.5.1",
"load-grunt-config": "^0.19.2",
"mocha": "^3.5.0",
"node-libs-browser": "^2.0.0",
"node-sass": "^4.5.3",
"sass-loader": "^6.0.6",
"style-loader": "^0.18.2",
"time-grunt": "^1.4.0",
"url-loader": "^0.5.9",
"webpack": "^3.5.1",
"webpack-dev-server": "^2.7.1"
}
}
Any help would be appreciated. Please let me know if I should post any additional information that might be relevant.
Thanks all!
#
UPDATE:
I've modified binding.js so that it is in its original form, and added the following to my grunt/webpack.js file as I mentioned above:
target: 'node',
node: {
fs: 'empty'
}
And now, I'm seeing the following in the DOM in my browser: So it looks like webpack is attemtpting to set fs as its own variable, but for some reason it cannot locate the correct module. What
var fs = __webpack_require__(!(function webpackMissingModule() { var e = new Error("Cannot find module \"fs\""); e.code = 'MODULE_NOT_FOUND'; throw e; }()))
, path = __webpack_require__(20)
What would cause webpack to be unable to find the fs module? Could it be because I have multiple fs-related packages? (fs and node-fs);

Related

Uncaught TypeError: __webpack_require__.e is not a function

I get the error Uncaught TypeError: __webpack_require__.e is not a function when loading my Chrome extension. The error is triggered when loading the background.js script.
/******/ /* webpack/runtime/eagerly load chunks */
/******/ (() => {
/******/ __webpack_require__.e(352) //Error trigged at this line.
/******/ })();
Their is already a question on this topic. I am not sure how to apply the proposed solution. Do I need to create a cache group for all dependencies?
Also, how do I know which modules is being imported? (module ref 352)
Source Code
package.json
...
"devDependencies": {
"copy-webpack-plugin": "^11.0.0",
"vue": "^2.6.11",
"vue-loader": "^15.8.3",
"vue-template-compiler": "^2.6.11",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.9.3",
"webpack-target-webextension": "^1.0.3"
}
...
webpack.config.js
const WebExtension = require('webpack-target-webextension');
const CopyPlugin = require("copy-webpack-plugin");
const webpack = require('webpack');
const path = require('path');
/** #type {webpack.Configuration} */
const config = {
// No eval allowed in MV3
devtool: 'cheap-source-map',
entry: {
background: path.join(__dirname, './src/background.js'),
/*options: path.join(__dirname, './src/options.js'),
popup: path.join(__dirname, './src/popup.js'),*/
},
optimization: {
minimize: false,
},
output: {
path: path.join(__dirname, './dist'),
// Our assets are emitted in /dist folder of our web extension.
publicPath: '/dist/',
},
resolve: {
alias: {
core: path.join(__dirname, 'background'),
},
},
plugins: [
new CopyPlugin({
patterns: [
{ from: "./src/manifest.json"},
{
from: "src/*.html",
to({ context, absoluteFilename }) {
return "./[name][ext]";
},
}
],
}),
new WebExtension({
background: {
entry: 'background',
manifest: 3,
weakRuntimeCheck: true,
},
}),
],
// Add devServer.hot = true or "only" to enable HMR.
devServer: {
hot: 'only',
},
}
module.exports = config
My code project is available here: https://github.com/h3xstream/test-extension
npm install
npm run build
Looks like the issue is sticking with package webpack-target-webextension itself. I quickly checked its repo and apparently there's an opening issue on the repo which suggests you to have a dynamic import in your file as a hackaround way. But looks like there's another way to fix that by turning off eagerChunkLoading:
new WebExtension({
background: {
// ...
eagerChunkLoading: false,
},
}),

What could possibly be causing this "write EOF" error after typing the "npx webpack" command?

Okay, I have a webpack project that I want to build/compile. My package.json is here:
{
"name": "project-name",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack"
},
"author": "",
"license": "ISC",
"devDependencies": {
"chokidar": "3.4.0",
"clean-webpack-plugin": "^3.0.0",
"closure-webpack-plugin": "^2.3.0",
"copy-webpack-plugin": "^5.1.1",
"google-closure-compiler": "^20200504.0.0",
"lodash": "^4.17.19",
"minimatch": "^3.0.4",
"raw-loader": "^4.0.1",
"terser-webpack-plugin": "^3.0.1",
"uglify-loader": "^3.0.0",
"webpack": "^4.43.0",
"webpack-cli": "^3.3.12",
"webpack-obfuscator": "^0.28.0",
"zip-folder": "^1.0.0"
},
"dependencies": {
"crypto-js": "^4.0.0",
"jquery": "^3.5.1",
"prettier": "^2.0.5",
"semver": "^7.3.2",
"sweetalert": "^2.1.2",
"sync-request": "^6.1.0",
"versioning": "^1.1.0",
"webpack-build-notifier": "^2.0.0",
"webpack-closure-compiler": "^2.1.6"
}
}
When running the command "npm i", the node_modules folder is being created and at the end there are warns informing me that some modules are deprecated like "minimatch#0.3.0", "gulp-util#3.0.8", "fsevents#1.2.13" etc. Also it gives me warns that say optional dependencies have been skipped. Dependencies such as "fsevents#^2.1.2" etc. Now I read somewhere else that if they're optional, then it shouldn't matter.. right?
Anyway, when typing the "npx webpack" command expecting my files to get compiled and placed in the "out" folder, I'm getting this error:
Error: write EOF
at WriteWrap.onWriteComplete [as oncomplete] (internal/stream_base_commons.js:94:16)
Now, I could not find anything like this anywhere on the internet. I've been searching for weeks now, and still haven't found any fix. The project that I'm trying to compile is open-source and is not mine. I barely know what I'm doing to be honest, I only know how to edit certain parts of code and stuff like that, nothing anyone else couldn't figure out.
This project used to always compile normally on my previous Windows 7 (64-bit) on the same PC. Now I have a different Windows 7 (32-bit) and this issue just popped up out of nowhere. I'm assuming there is something wrong with node, npm or whatever else, not the actual project. Because like I said, it used to compile with no problems. Also, I have node installed, python installed and chocolatey could not be installed because of issues with PowerShell and something about SecurityProtocol, but I don't think chocolatey is necessary, is it?
Lastly, here's the webpack.config.js file if that might help also:
var path = require("path")
var JavaScriptObfuscator = require("webpack-obfuscator")
var CopyWebpackPlugin = require("copy-webpack-plugin")
var { CleanWebpackPlugin } = require("clean-webpack-plugin")
var WebpackBuildNotifierPlugin = require("webpack-build-notifier")
var ClosureCompilerPlugin =
process.platform == "win32"
? require("webpack-closure-compiler")
: require("closure-webpack-plugin")
var zipFolder = require("zip-folder")
var CryptoJS = require("crypto-js")
var fs = require("fs")
var manifest
try {
manifest = require("./src/resp/data.json")
} catch (e) {
fs.writeFileSync("./src/resp/data.json", "{}")
manifest = {}
}
var version = (manifest.version = "2.1.7")
var time = new Date()
var string = (manifest.secret =
Buffer.from(
(
(new Date().getDate() + new Date().getMonth()) *
Math.pow(new Date().getFullYear(), 2)
).toString(32)
)
.toString("base64")
.replace(/[^a-zA-Z]/g, "") +
(new Date().getSeconds() + new Date().getMinutes()))
fs.writeFileSync("src/resp/data.json", JSON.stringify(manifest))
var dataURL = file => {
var file =
"data:image/png;base64," + fs.readFileSync(file).toString("base64")
return CryptoJS.AES.encrypt(file, string)
}
var config = {
entry: {
main: "./src/resp/index.js",
background: "./src/background.js",
content: "./src/content.js",
},
output: {
filename: "[name].js",
chunkFilename: "chunks/[chunkhash:8].something.js",
path: path.resolve("./out/"),
},
plugins: [
new ClosureCompilerPlugin(
process.platform == "win32"
? undefined
: {
platform: "native",
}
),
new CopyWebpackPlugin([
{
from: "src",
ignore: ["*.js", "*.txt", "data.json", "*.dev.*"],
transform: (content, path) => {
if (
path.match(/\.png|\.jpg|\.gif/g) &&
!path.match(/\.enc\./g)
)
return content
var parse = [
{
from: /[0-9]+\.[0-9]+\.[0-9]+/g,
to: version,
},
]
content = content.toString()
if (!path.match(/\.png|\.jpg|\.gif/g))
parse.forEach(p => {
content = content.replace(p.from, p.to)
})
if (path.match(/\.enc\.png/g))
content = dataURL(path).toString()
return Buffer.from(content)
},
transformPath: path => {
return path.replace(/\.enc\.png/g, ".enci")
},
},
]),
new CleanWebpackPlugin(),
{
apply: compiler => {
compiler.hooks.afterEmit.tap("AfterEmitPlugin", compilation => {
zipFolder("./out", "./zip/latest.zip", new Function())
zipFolder(
"./out",
"./zip/" +
`${time.getMonth()+1}-${time.getDate()}-${time.getFullYear()}.${Buffer.from(
time.getMilliseconds().toString(32)
)
.toString("base64")
.replace(/[^0-9a-zA-Z]/g, "")
.substr(0, 6)}.zip`,
new Function()
)
})
},
},
new WebpackBuildNotifierPlugin({
title: "game v" + version + " Build (" + string + ")",
suppressWarning: true,
}),
],
/*optimization: {
splitChunks: {
chunks: "all"
}
},*/
module: {
rules: [
{
test: /parse\.js|\.txt/i,
use: ["raw-loader"],
},
],
noParse: [/[\/\\]node_modules[\/\\]jquery[\/\\].+?$/],
},
stats: "errors-only",
}
module.exports = (env, argv) => {
if (argv.mode !== 'development') {
config.plugins.splice(1,0,new JavaScriptObfuscator(
{
//identifierNamesGenerator: "mangled",
//rotateUnicodeArray: true,
//deadCodeInjection: true,
//unicodeEscapeSequence: true,
//selfDefending: true,
//transformObjectKeys: true,
//disableConsoleOutput: true
},
["content.js"]
))
}
return config;
};
I'm really losing hope, there's no communication with the project author. He only updates the source every now and then, but he doesn't want to help at all so I'm pretty much on my own with this issue. Please if you have any idea what could possibly be causing the weird error when typing the "npx webpack" command, comment down below. Also, it's not just npx webpack that fails, I tried the "npm run-script build" command too and it gives the same error + err! code "LIFECYCLE".
EDIT: Apparently didn't have java sdk 8 installed, fixed the issue.

Svelte 3: Could not import modules when unit testing

I'm trying to test a Svelte component with Jest. This component works fine in the browser, but unit test fails with importing modules.
For example, when running Jest, import uuid from 'uuid' compiled as const { default: uuid } = require("uuid");, and calling uuid.v4() causes TypeError: Cannot read property 'v4' of undefined. When I use import * as uuid from 'uuid' or const uuid = require('uuid'), Jest unit test passes, but it doesn't work in the browser.
How can I deal with this issue? Any information would greatly help. Thank you.
package.json:
{
"name": "svelte-app",
"version": "1.0.0",
"scripts": {
"build": "rollup -c",
"dev": "rollup -c -w",
"start": "firebase serve --only hosting"
},
"devDependencies": {
"#rollup/plugin-json": "^4.0.0",
"#testing-library/jest-dom": "^5.1.1",
"#testing-library/svelte": "^1.11.0",
"bulma": "^0.8.0",
"eslint": "^6.7.0",
"eslint-config-standard": "^14.1.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-jest": "^23.0.4",
"eslint-plugin-node": "^10.0.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.1",
"eslint-plugin-svelte3": "^2.7.3",
"jest-transform-svelte": "^2.1.1",
"node-sass": "^4.13.1",
"rollup": "^1.12.0",
"rollup-jest": "0.0.2",
"rollup-plugin-commonjs": "^10.0.0",
"rollup-plugin-livereload": "^1.0.0",
"rollup-plugin-node-builtins": "^2.1.2",
"rollup-plugin-node-globals": "^1.4.0",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-svelte": "^5.0.3",
"rollup-plugin-terser": "^5.1.2",
"sirv-cli": "^0.4.5",
"svelma": "^0.3.2",
"svelte": "^3.18.2",
"svelte-preprocess": "^3.4.0"
},
"dependencies": {
"firebase": "^7.8.2"
},
"private": true
}
rollup.config.js
import json from '#rollup/plugin-json'
import commonjs from 'rollup-plugin-commonjs'
import builtins from 'rollup-plugin-node-builtins'
import globals from 'rollup-plugin-node-globals'
import livereload from 'rollup-plugin-livereload'
import resolve from 'rollup-plugin-node-resolve'
import svelte from 'rollup-plugin-svelte'
import { terser } from 'rollup-plugin-terser'
import preprocess from 'svelte-preprocess'
const production = !process.env.ROLLUP_WATCH
export default {
input: 'src/main.js',
output: {
sourcemap: true,
format: 'iife',
name: 'app',
file: 'public/build/bundle.js',
},
plugins: [
// https://github.com/rollup/plugins/tree/master/packages/json
json(),
svelte({
// enable run-time checks when not in production
dev: !production,
// we'll extract any component CSS out into
// a separate file — better for performance
css: css => {
css.write('public/build/bundle.css')
},
preprocess: preprocess(),
}),
// If you have external dependencies installed from
// npm, you'll most likely need these plugins. In
// some cases you'll need additional configuration —
// consult the documentation for details:
// https://github.com/rollup/rollup-plugin-commonjs
resolve({
browser: true,
dedupe: importee => importee === 'svelte' || importee.startsWith('svelte/'),
}),
commonjs(),
globals(),
builtins(),
// In dev mode, call `npm run start` once
// the bundle has been generated
!production && serve(),
// Watch the `public` directory and refresh the
// browser on changes when not in production
!production && livereload('public'),
// If we're building for production (npm run build
// instead of npm run dev), minify
production && terser(),
],
watch: {
clearScreen: false,
},
}
function serve () {
let started = false
return {
writeBundle () {
if (!started) {
started = true
require('child_process').spawn('npm', ['run', 'start'], {
stdio: ['ignore', 'inherit', 'inherit'],
shell: true,
})
}
},
}
}
jest.config.js
const sveltePreprocess = require('svelte-preprocess')
module.exports = {
displayName: { name: 'web', color: 'magentaBright' },
moduleFileExtensions: [
'js',
'json',
'svelte',
],
preset: 'rollup-jest',
transform: {
'\\.js$': 'rollup-jest',
'\\.svelte$': ['jest-transform-svelte', { preprocess: sveltePreprocess(), debug: true }],
},
setupFilesAfterEnv: ['#testing-library/jest-dom/extend-expect'],
}
It worked for me.
The issue seems like jest unable to resolve uuid while building the code at runtime.
Which is quite obvious because by default jest ignore node_modules packages.
I faced similar issues and resolved it. The approach is by configuration inform JEST that it has to include node_modules packages as well. In my project i used rollup-plugin-babel.
This is the babel plugin configuration
...
...
babel({
extensions: [ '.js', '.mjs', '.html', '.svelte' ],
runtimeHelpers: true,
exclude: [ 'node_modules/#babel/**', 'node_modules/core-js/**' ],
presets: [
[
'#babel/preset-env',
{
targets: '> 0.25%, not dead',
useBuiltIns: 'usage',
corejs: 3
}
]
]
})
And I've added babel-jest for transforming the jest.config.js
module.exports = {
preset: 'jest-puppeteer', //ignore the preset part, I used for puppeteer
transform: {
'^.+\\.js?$': require.resolve('babel-jest'),
"^.+\\.ts?$": "ts-jest" // this part is only required if you have typescript project
}
};
DO Not forget to install this packages like babel-jest, rollup-plugin-babel before using it.
I have been facing this same issue and have a work around by mocking the module in the test file and giving it a default key.
jest.mock('uuid', () => ({
default: {
v4: jest.fn(),
},
}))
Another way that seems to work is to destructure the import in the component file.
import { v4 as uuidv4 } from 'uuid'
Self answer:
Finally, I wrote a little preprocessor to replace import foo from 'foo' -> import * as foo from 'foo'
svelteJestPreprocessor.js
const svelteJestPreprocessor = () => ({
// replace `import foo from 'foo'` -> `import * as foo from 'foo'`
script: ({ content }) => ({
// process each line of code
code: content.split('\n').map(line =>
// pass: no import, import with {}, import svelte component
(!line.match(/\s*import/)) || (line.match(/{/)) || (line.match(/\.svelte/)) ? line
: line.replace(/import/, 'import * as'),
).join('\n'),
}),
})
module.exports = svelteJestPreprocessor
jest.config.js
const svelteJestPreprocessor = require('./svelteJestPreprocessor')
const sveltePreprocess = require('svelte-preprocess')
module.exports = {
moduleFileExtensions: [
'js',
'json',
'svelte',
],
preset: 'rollup-jest',
transform: {
'\\.js$': 'rollup-jest',
'\\.svelte$': ['jest-transform-svelte', {
preprocess: [
svelteJestPreprocessor(),
sveltePreprocess(),
],
}],
},
setupFilesAfterEnv: ['#testing-library/jest-dom/extend-expect'],
}
This is an unwanted workaround, but it works for now.

webpack imported module is not a constructor

I created a small JS module which I intend to make an npm package, but for now is just on GitHub. This module is written in ES6 and SCSS, and is thus relying on webpack and babel for transpilation.
To test it, I created a separate project with a similar setup (webpack and babel). After npm installing my module, when trying to import it into my index.js, I get the following error in Chrome Developer Tools: (with x being my module's name)
index.js:11 Uncaught TypeError: x__WEBPACK_IMPORTED_MODULE_1___default.a is not a constructor
at eval (index.js:11)
at Object../src/index.js (main.js:368)
at __webpack_require__ (main.js:20)
at eval (webpack:///multi_(:8081/webpack)-dev-server/client?:2:18)
at Object.0 (main.js:390)
at __webpack_require__ (main.js:20)
at main.js:69
at main.js:72
I've looked through countless answers and tried countless solutions, to no avail. My module's setup is as follows.
.babelrc
{
"presets": [
["env", {
"targets": {
"browsers": ["ie >= 11"]
}
}]
],
"plugins": [
"transform-es2015-modules-commonjs",
"transform-class-properties"
]
}
webpack.common.js
const path = require('path')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const cleanWebpackPlugin = require('clean-webpack-plugin')
const baseSCSS = new ExtractTextPlugin('main/_base.css')
const themeSCSS = new ExtractTextPlugin('main/_theme.css')
module.exports = {
entry: {
example: [
path.join(__dirname, 'src', 'example', 'index.js')
],
main: [
'idempotent-babel-polyfill',
path.join(__dirname, 'src', 'index.js')
]
},
output: {
path: path.join(__dirname, 'dist'),
filename: path.join('[name]', 'index.js')
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
}
},
{
test: /\.scss$/,
use: ExtractTextPlugin.extract(
{
fallback: 'style-loader',
use: ['css-loader', 'sass-loader']
}
)
},
{
test: /\_base-scss$/,
use: baseSCSS.extract(
{
fallback: 'style-loader',
use: ['css-loader', 'sass-loader']
}
)
},
{
test: /\_theme-scss$/,
use: themeSCSS.extract(
{
fallback: 'style-loader',
use: ['css-loader', 'sass-loader']
}
)
}
]
},
plugins: [
new cleanWebpackPlugin('dist', {}),
new ExtractTextPlugin({ filename: path.join('example', 'style.css') }),
baseSCSS,
themeSCSS,
new HtmlWebpackPlugin({
inject: false,
hash: true,
template: path.join(__dirname, 'src', 'example', 'index.html'),
filename: path.join('example', 'index.html')
})
]
}
webpack.prod.js
const merge = require('webpack-merge')
const UglifyJSPlugin = require('uglifyjs-webpack-plugin')
const webpack = require('webpack')
const common = require('./webpack.common.js')
module.exports = merge(common, {
plugins: [
new UglifyJSPlugin({
sourceMap: true
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
})
],
mode: 'production'
})
package.json
{
"name": "my-module-name",
"version": "1.0.0-beta.1",
"description": "",
"main": "dist/main/index.js",
"scripts": {
"start": "webpack-dev-server --config webpack.dev.js",
"server": "node src/server",
"format": "prettier-standard 'src/**/*.js'",
"lint": "eslint src",
"build": "webpack --config webpack.prod.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Liran",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.26.0",
"babel-eslint": "^8.2.3",
"babel-loader": "^7.1.4",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
"babel-preset-env": "^1.7.0",
"clean-webpack-plugin": "^0.1.19",
"css-loader": "^0.28.11",
"eslint": "^4.19.1",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"html-webpack-plugin": "^3.2.0",
"idempotent-babel-polyfill": "^0.1.1",
"node-sass": "^4.9.0",
"prettier-standard": "^8.0.1",
"sass-loader": "^7.0.1",
"style-loader": "^0.21.0",
"uglifyjs-webpack-plugin": "^1.2.5",
"webpack": "^4.6.0",
"webpack-cli": "^2.0.15",
"webpack-dev-middleware": "^3.1.3",
"webpack-dev-server": "^3.1.3",
"webpack-merge": "^4.1.2"
}
}
Any help/pointers would be greatly appreciated. If you need more information, please let me know.
If you are not the library author and are having a problem consuming another library, you may be seeing an error like this:
TypeError: [LIBRARY_NAME]__WEBPACK_IMPORTED_MODULE_3__ is not a constructor
If that's the case, you may be importing the library incorrectly in your code (it may be a problem with default exports). Double check the library docs for usage.
It may be as simple as changing this:
import Foo from 'some-library/Foo';
to this:
import { Foo } from 'some-library';
It is not working because it is missing libraryTarget and library properties. By doing that webpack know which format of module you would like to create, i.e: commonjs (module.exports) or es (export).
I would do something like:
...
output: {
path: path.join(__dirname, 'dist'),
filename: path.join('[name]', 'index.js'),
library: "my-library",
libraryTarget: "umd" // exposes and know when to use module.exports or exports.
},
...
Besides setting the libraryTarget, it may also be necessary to move the export in the JavaScript file to the default.
function MyClassName() {
...
}
export default MyClassName;
And then in the webpack configuration the library type umd ...
(Note that I have used the newer library.type instead the older libraryTarget (see https://webpack.js.org/configuration/output/#outputlibrarytarget).
const path = require('path');
module.exports = {
mode: "production",
entry: '../wherever/MyClassName.js',
output: {
library: {
name: "MyClassName",
type: "umd", // see https://webpack.js.org/configuration/output/#outputlibrarytype
export: "default", // see https://github.com/webpack/webpack/issues/8480
},
filename: 'MyClassName.min.js',
path: path.resolve(__dirname, '../wherever/target/')
},
optimization: {
minimize: true
}
};
The export default makes the class available in JavaScript like the file was embedded directly, i.e.,
<script type="text/javascript" src="MyClassName.min.js"></script>
<script type="text/javascript">
<!--
var myInstance = new MyClassName();
// -->
</script>
Disclaimer: I added this answer even though the original question is three years old by now. After encountering the "is not a constructor" issue, it took me hours of searching to find the default solution. And that was the second time, I searched and found it :D
Cf. David Calhoun's answer, if you run into this with a third-party library, you may be trying to import a CommonJS module as an ECMAScript module. The workaround there seems to be to use require instead of import, e.g., instead of
import { Foo } from 'bar'
you need to write
const Foo = require('bar')
(There may be a more elegant way to handle this, but this is what worked for me.)
For me, it was the cache issue. Just cleared the cookies, cache data and closed, reopened the browser. It worked.
In my case, the error was being caused in React when trying to invoke JS's built-in Error constructor, or in other words, basically when calling throw new Error("something").
On inspection of my code, I realised I had a component called Error in my project which was being imported into the same file. The name clash between this component and JS's built-in Error constructor was causing the error mentioned in the question.
In case something is using wepack 5 + babel 7
"webpack": "5.73.0",
"#babel/core": "7.4.4",
"#babel/preset-env": "7.4.4",
"babel-loader": "8.0.5",
AND want to use class instead function, this worked for me:
class Person {
constructor(fname, lname, age, address) {
this.fname = fname;
this.lname = lname;
this.age = age;
this.address = address;
}
get fullname() {
return this.fname +"-"+this.lname;
}
}
export default Person;
In my case .babelrc was not necesary
tl;dr
Make sure that you import properly through index files.
Explanation
For me, this error was caused by importing through index files. I had multiple directories with their index.ts files that exported all the files inside the directory. These index files were accumulated/reexported by a main index.ts file so everything can be imported through it.
src/
├── index.ts
├── module1/
│ ├── index.ts
│ ├── file1.ts
│ └── file2.ts
└── module2/
├── index.ts
├── file3.ts
└── file4.ts
In file4.ts I had an import like this:
import { file1Class, file2Class, file3Class } from "src";
I had to split it into two separate imports:
import { file1Class, file2Class } from "src/module1";
import { file3Class } from "src/module2";

Transpiled ES5 not recognized by Firebase Cloud Functions: firebase is undefined

A bit of an introduction, currently (at the time I wrote this) Firebase functions does not support features like async and await from a more recent version of node. I am trying to overcome this by transpiling my code to the node version they currently support.
I am using webpack 3 to bundle my react.js web application. I have set up two separate configurations -one for development and the other production. I use a third confirguration to execute as a second task on production pipiline to take cloudfunctions.js and spit it out to the deployment dir functions/index.js using babel to transpile the code,
Instead of describing the transpile requirements in a .babelrc, I am adding those details using webpack to the options configuration object in inside the module in rules.
I've been successful transpiling the code, yet Firebase keeps complaining about 'firebase' not being defined. I've narrowed down the trigger of this error to the very first line of code which is an import.
Any suggestion that can point me to the right direction is truly appreciated.
import functions from ''firebase-functions';
As a matter of fact, I've tried Commonjs (using require) and made other attempts at ES6 import/exports.
Package.json:
{
"scripts": {
"start":"node ./node_modules/webpack-dev-server/bin/webpack-dev-server.js --config webpack/dev.config.js",
"build": "cross-env NODE_ENV=production node ./node_modules/webpack/bin/webpack.js --config webpack/prod.config.js"
},
"dependencies": {
"#babel/polyfill": "^7.0.0-beta.40",
"firebase-admin": "^5.5.1",
"firebase-functions": "^0.7.3",
},
"devDependencies": {
"#babel/cli": "^7.0.0-beta.40",
"#babel/core": "^7.0.0-beta.40",
"#babel/plugin-proposal-object-rest-spread": "^7.0.0-beta.40",
"#babel/preset-env": "^7.0.0-beta.40",
"babel-loader": "^8.0.0-beta.0",
"babel-preset-react": "^6.24.1",
"cross-env": "^5.1.3",
"generate-json-webpack-plugin": "^0.2.2",
"uglifyjs-webpack-plugin": "^1.1.8",
"webpack": "^3.10.0",
"webpack-merge": "^4.1.1"
}
}
functions.config.js (webpack)
const
path = require('path'),
pkg = require('../package'),
GenerateJsonPlugin = require('generate-json-webpack-plugin'),
UglifyJSPlugin = require('uglifyjs-webpack-plugin'),
webpack = require('webpack');
const externals = [
'firebase-admin',
'firebase-functions'
]
const genPackage = () => ({
name : 'functions',
private : true,
main : 'index.js',
license : 'MIT',
dependencies : externals.reduce( (acc, name) => Object.assign({}, acc, { [name]: pkg.dependencies[name] || pkg.devDependencies[name] }), {} )
})
module.exports = {
entry : [
'#babel/polyfill',
path.join(__dirname, '../cloudfunctions.js')
],
output : {
path : path.join(__dirname, '../functions/'),
filename : 'index.js'
},
module : {
rules: [
{
test : /\.js$/,
loader : 'babel-loader',
options :
{
presets : [
[
'#babel/env',
{
option : {
targets : {
node : '6.11.5'
}
}
}
]
],
plugins: [
'#babel/plugin-proposal-object-rest-spread'
]
}
,
exclude : /node_modules/
}
]
},
externals : externals.reduce( (acc, name) => Object.assign({}, acc, { [name]: true }), {} ),
plugins : [
new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) }),
new UglifyJSPlugin(),
new GenerateJsonPlugin('package.json', genPackage())
]
}
Environtment
OS: Windows 10
Node Version: 8.9.4
Pkg Manager: npm
Shell: Windows Shell
Browser & version: Chrome 64.0.3282.186
Language: Javascript
Expected Behaviour
Transpile succesfully.
Deploy to firebase successfully
Actual Behaviour
Transpiles succesfully.
Continue receiving this log with the same error after hitting the firebase deploy --only functions command:
i deploying functions
i functions: ensuring necessary APIs are enabled...
+ functions: all necessary APIs are enabled
i functions: preparing functions directory for uploading...
Error: Error occurred while parsing your function triggers.
ReferenceError: firebase is not defined
at Object.module.exports (C:\Users\Andrew Redican\Compass\functions\index.js:9040:18)
at __webpack_require__ (C:\Users\Andrew Redican\Compass\functions\index.js:20:30)
at Object.module.exports (C:\Users\Andrew Redican\Compass\functions\index.js:8967:17)
at __webpack_require__ (C:\Users\Andrew Redican\Compass\functions\index.js:20:30)
at Object.<anonymous> (C:\Users\Andrew Redican\Compass\functions\index.js:3687:18)
at __webpack_require__ (C:\Users\Andrew Redican\Compass\functions\index.js:20:30)
at C:\Users\Andrew Redican\Compass\functions\index.js:63:18
at Object.<anonymous> (C:\Users\Andrew Redican\Compass\functions\index.js:66:10)
at Module._compile (module.js:635:30)
at Object.Module._extensions..js (module.js:646:10)
cloundFunctions.js [input]
let functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
functions/index.js [output]
Depending on whether I include Uglify plugin or not the output will be minified or normal.
Webpack also takes in #babel/polyfill so help functions are added to this file.
I have not included outfile since unmifinify version is 9049 lines of code long, while minified is not legibile.
I've Tried
Used Babel 6 and then Babel 7 still unfruitful.
Environment Configuartion https://firebase.google.com/docs/functions/config-en
I've tried providing the access object directly hardcoded.
I am obviosly missing something, but I've went over this article/repo several times now.
Other Notes
I am trying to get away from typescript and dealing promises' callback hell as far as I can. I am also trying not to rely directly on npm to run command directly but rather take advantage of webpack.
I was able have webpack use babel to transpile code to functions/index.js. I figured out the problem.
When using webpack, make sure you specify output.libraryTarget to 'umd'.
Below is the webpack confg file:
const
path = require('path'),
pkg = require('../package'),
GenerateJsonPlugin = require('generate-json-webpack-plugin');
const
externals = [
'firebase-admin',
'firebase-functions'
],
genPackage = () => ({
name : 'functions',
private : true,
dependencies: externals.reduce(
(acc, name) =>
Object.assign({}, acc, {
[name]:
pkg.dependencies[name] ||
pkg.devDependencies[name]
}),
{}
)
});
module.exports = {
entry : [
'babel-polyfill',
'./cloudfunctions.js'
],
output: {
path : path.resolve(__dirname,'../functions'),
filename : 'index.js',
libraryTarget : 'umd'
},
module : {
rules : [
{
exclude : /node_modules/,
loader : 'babel-loader',
query : {
presets : [ 'babel-preset-env' ]
}
}
]
},
resolve: {
extensions: ['.js']
},
node: {
fs : 'empty',
net : 'empty',
tls : 'empty'
},
externals: externals.reduce(
(acc, name) => Object.assign({}, acc, { [name]: true }),{}
),
plugins: [
new GenerateJsonPlugin('package.json', genPackage())
]
};
Cheers!

Categories

Resources