no window object present webpack nodejs - javascript

I'm using webpack with babel to compile my ecmascript 6 code. Everything works fine but if I add certain dependeciens like the requests npm package. Here are my files:
main.js
import os from 'os'
export class User {
constructor(username) {
this.username = username;
}
register() {
console.log("registering...");
}
}
var client = new User("hey")
console.log(user.register());
webpack config:
var webpack = require('webpack')
module.exports = {
entry: [
'./src/main.js'
],
output: {
path: "dist",
publicPath: "/dist/",
filename: "stela.js"
},
watch: false,
module: {
loaders: [{
test: /\.js$/,
// excluding some local linked packages.
// for normal use cases only node_modules is needed.
exclude: /node_modules/,
loader: 'babel'
}, {
test: /\.json$/,
loader: 'json-loader'
}]
},
externals: {
fs: '{}',
tls: '{}',
net: '{}',
console: '{}'
},
babel: {
presets: ['es2015'],
plugins: ['transform-runtime']
},
resolve: {
modulesDirectories: ['node_modules']
}
}
Now if I run webpack and then run node dist/stella.js everything works fine it logs out registering...; however, if I add certain dependencies like the requests npm package:
...
import request from 'request'
...
I run webpack everything compiles down with no errors but then I try running node dist/stella.js and I get this error:
throw new Error('no window object present');

By default, Webpack is set up to target the browser, not a Node environment. Try setting target in your config:
module.exports = {
// ...
target: "node",
// ...
}

Related

Webpack can't resolve relative path import express static

I'm working on an outlook addin I have an express server running. I am setting webpack because I need to transpile js to es5 to make it work in Outlook Desktop. Here is the simplified project structure.
/public
/javascripts
ssoAuth.js
/addin
/commmands
commands.js
commands.html
/server
/bin
/helpers
app.js
The public folder is set as a static folder in my express server
app.use(express.static(path.join(__dirname, '../public'),
My problem is in commands.js I import ssoAuth.js with es6 module import with relative path :
import getGraphAccessToken from "/javascripts/ssoAuthES6.js";
It works fine when I run node ./server/app.js and load my outlook addin, but when I want to use Webpack to bundle, the import is not working, I get :
ERROR in ./addin/commands/commands.js
Module not found: Error: Can't resolve '/javascripts/ssoAuth.js'
I can't figure out how to configure webpack to allow the imports from the public folder.
Here are my webpack config files :
webpack.config.js :
const config = {
devtool: "source-map",
entry: {
polyfill: "#babel/polyfill",
commands: "./addin/commands/commands.js"
},
resolve: {
extensions: [".ts", ".tsx", ".html", ".js"]
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["#babel/preset-env"]
}
}
},
{
test: /\.html$/,
exclude: /node_modules/,
use: "html-loader"
},
{
test: /\.(png|jpg|jpeg|gif)$/,
use: "file-loader"
}
]
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
filename: "commands.html",
template: "./addin/commands/commands.html",
chunks: ["polyfill", "commands"]
})
]};
webpack.server.config.js :
return ({
entry: {
server: './server/bin/www',
},
output: {
path: path.join(__dirname, 'dist'),
publicPath: '/',
filename: '[name].js'
},
target: 'node',
node: {
__dirname: false,
__filename: false,
},
externals: [nodeExternals()],
module: {
rules: [
{
// Transpiles ES6-8 into ES5
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
}
]
},
plugins: [
new CopyWebpackPlugin([
{
to: "./public",
from: "./public"
}
])
]})
Can you help figure this out ? Is there a better folder structure that I should use to make it work ?
Thanks
You're using an absolute path
import getGraphAccessToken from "/javascripts/ssoAuthES6.js";
// ^ this will look in your topmost directory on your OS
The relative path, from commands.js, would be:
import getGraphAccessToken from "../../javascripts/ssoAuthES6.js";
Alternatively, you can set Webpack to look for modules from your root directory by adding the following to your webpack configuration:
{
// ...
resolve: {
modules: [path.resolve(__dirname, "src"), "node_modules"],
},
// ...
}
Then you can import from your project's root directory from anywhere, like so:
import getGraphAccessToken from "javascripts/ssoAuthES6.js";
Some other points:
Since you're setting the extensions: [".ts", ".tsx", ".html", ".js"], you don't need to provide file extensions for those imports
You specify .ts and .tsx in your webpack config, but you are using .js files. Consider removing the Typescript extensions
If you are using Typescript, you will need to update import paths in your tsconfig.json
You can consider import path aliases in both Webpack and Typescript to be more explicit that your imports are coming from your project root. Instructions here

Building Gatsby components using Webpack cannot transpile Gatsby module

I am trying to make a library of Gatsby components (using specific Gatsby library rather than general React components).
I have been compiling using just babel but I want to be able to translate any CSS-in-JS and do other things so I am trying to build using Webpack.
When I try to compile the Gatsby component it fails in the Gatsby module. I know Gatsby is untranspiled ES6 so I included node_modules in my webpack configuration to transpile but I still:
ERROR in ./node_modules/gatsby/cache-dir/gatsby-browser-entry.js
Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: /Users/kylecalica/Code/gatsby-learn/gatsby-components/node_modules/gatsby/cache-dir/gatsby-browser-entry.js: Unexpected token (25:4)
23 |
24 | return (
> 25 | <React.Fragment>
| ^
26 | {finalData && render(finalData)}
27 | {!finalData && <div>Loading (StaticQuery)</div>}
28 | </React.Fragment>
Webpack:
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const htmlWebpackPlugin = new HtmlWebpackPlugin({
filename: "index.html"
});
module.exports = {
entry: path.join(__dirname, "/src/index.js"),
output: {
filename: 'main.js',
path: path.resolve(__dirname, "/webpack/dist")
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: {
loader: "babel-loader"
}
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
]
},
plugins: [htmlWebpackPlugin],
devServer: {
contentBase: path.join(__dirname, "dist"),
port: 9000,
open: true
}
};
I am currently trying to take what Gatsby says to do to Storybook in my code but it's hard to figure out how to translate this from their strange way into mine?
Storybook's way of webpack:
module.exports = ({ config }) => {
// Transpile Gatsby module because Gatsby includes un-transpiled ES6 code.
config.module.rules[0].exclude = [/node_modules\/(?!(gatsby)\/)/]
// use installed babel-loader which is v8.0-beta (which is meant to work with #babel/core#7)
config.module.rules[0].use[0].loader = require.resolve("babel-loader")
// use #babel/preset-react for JSX and env (instead of staged presets)
config.module.rules[0].use[0].options.presets = [
require.resolve("#babel/preset-react"),
require.resolve("#babel/preset-env"),
]
config.module.rules[0].use[0].options.plugins = [
// use #babel/plugin-proposal-class-properties for class arrow functions
require.resolve("#babel/plugin-proposal-class-properties"),
// use babel-plugin-remove-graphql-queries to remove static queries from components when rendering in storybook
require.resolve("babel-plugin-remove-graphql-queries"),
]
// Prefer Gatsby ES6 entrypoint (module) over commonjs (main) entrypoint
config.resolve.mainFields = ["browser", "module", "main"]
return config
}
.babelrc :
{
"presets": [
"babel-preset-gatsby-package",
"#babel/preset-react",
"#babel/preset-env"
]
}
I solved this by converting what Storybook's webpack module had. I am still putting it through testing however but it compiles fine for now:
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const htmlWebpackPlugin = new HtmlWebpackPlugin({
filename: "index.html"
});
module.exports = {
entry: path.join(__dirname, "/src/index.js"),
output: {
filename: 'index.js',
path: path.resolve(__dirname, "webpack")
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: {
loader: "babel-loader",
options: {
presets: ["babel-preset-gatsby-package"],
plugins: ["#babel/plugin-proposal-class-properties"]
},
},
exclude: [/node_modules\/(?!(gatsby)\/)/],
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
]
},
plugins: [htmlWebpackPlugin],
devServer: {
contentBase: path.join(__dirname, "dist"),
port: 9000,
open: true
}
};

Run Mocha specs from React app in a browser using Webpack and mocha-loader

I have a react App for which I'd like to run its mocha specs (unit-tests) in a browser. I found this SO post and tried to apply same idea to my project. I came up with the following webpack config file:
webpack.config.test.js
const nodeExternals = require('webpack-node-externals');
const path = require('path');
const host = 'localhost';
const port = '8084';
module.exports = {
target: 'web',
externals: [nodeExternals()],
entry: './specs/index.js',
output: {
filename: 'debug.bundle.js',
path: path.join(__dirname, 'tests'),
publicPath: `http://${host}:${port}/tests`,
},
devServer: {
host,
port,
},
module: {
rules: [
{
test: /\.js$/,
loaders: ['react-hot-loader', 'babel-loader'],
enforce: 'pre',
},
{
test: /.+Spec\.js$/,
loaders: ['mocha-loader'],
},
{
test: /(\.css|\.scss)$/,
loader: 'null-loader',
exclude: [
/build/,
],
},
{
test: /(\.jpg|\.jpeg|\.png|\.gif)$/,
loader: 'null-loader',
},
],
},
};
And, after starting the server with:
webpack-dev-server --config webpack.config.test.js
I get the following error in console:
I've read that the problem might be with webpack-node-externals but not really sure what's happening. Any ideas?
I think you will want to use webpack-node-externals only when you bundle files for backend (as described in plugin README). When you use it you forbid it to build all modules from node_modules folder.

Still getting 'Symbol' is undefined' error even after adding babel-polyfill in my webpack

https://babeljs.io/docs/usage/polyfill/#usage-in-browser
I did not understand the lines on the documentation page under:
Usage in Browser heading
can someone help me with what else is required:
Below are my code snippets:
I'm using storybook as a boilerplate:
webpack.config.js file:
entry: [
'babel-polyfill',
require.resolve('react-dev-utils/webpackHotDevClient'),
paths.appIndexJs
]
index.js file:
import 'babel-polyfill';
import React from 'react';
Is there some other files also where I need to add babel-polyfill related code.
require('babel-polyfill');
var path = require('path');
var autoprefixer = require('autoprefixer');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
var InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
var WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
var getClientEnvironment = require('./env');
var paths = require('./paths');
var publicPath = '/';
var publicUrl = '';
var env = getClientEnvironment(publicUrl);
module.exports = {
devtool: 'cheap-module-source-map',
entry: ['babel-polyfill',
require.resolve('react-dev-utils/webpackHotDevClient'),
require.resolve('./polyfills'),
paths.appIndexJs
],
output: {
path: paths.appBuild,
pathinfo: true,
filename: 'static/js/bundle.js',
publicPath: publicPath
},
resolve: {
fallback: paths.nodePaths,
extensions: ['.js', '.json', '.jsx', ''],
alias: {
'react-native': 'react-native-web'
}
},
module: {
// First, run the linter.
// It's important to do this before Babel processes the JS.
preLoaders: [{
test: /\.(js|jsx)$/,
loader: 'eslint',
include: paths.appSrc,
}],
loaders: [{
exclude: [/\.html$/, /\.(js|jsx)$/, /\.css$/, /\.json$/],
loader: 'url',
query: {
limit: 10000,
name: 'static/media/[name].[hash:8].[ext]'
}
},
// Process JS with Babel.
{
test: /\.(js|jsx)$/,
include: paths.appSrc,
loader: 'babel',
query: {
cacheDirectory: true
}
}, {
test: /\.css$/,
loader: 'style!css?importLoaders=1!postcss'
}, {
test: /\.json$/,
loader: 'json'
}
]
},
// We use PostCSS for autoprefixing only.
postcss: function() {
return [
autoprefixer({
browsers: ['>1%', 'last 4 versions', 'Firefox ESR', 'not ie < 9', // React doesn't support IE8 anyway
]
}),
];
},
plugins: [
new InterpolateHtmlPlugin({
PUBLIC_URL: publicUrl
}),
new HtmlWebpackPlugin({
inject: true,
template: paths.appHtml,
}),
new webpack.DefinePlugin(env),
new webpack.HotModuleReplacementPlugin(),
new CaseSensitivePathsPlugin(),
new WatchMissingNodeModulesPlugin(paths.appNodeModules)
],
node: {
fs: 'empty',
net: 'empty',
tls: 'empty'
}
};
There are two ways to get this code into your browser.
1 - Include the babel-polyfill module in the webpack bundle
2 - Load it as an external script in your html
Webpack - adding bundle dependencies with entry arrays
Put an array as the entry point to make the babel-polyfill module available to your bundle as an export.
With webpack.config.js, add babel-polyfill to your entry array.
The webpack docs explain how an entry array is handled:
What happens when you pass an array to entry? Passing an array of file
paths to the entry property creates what is known as a "multi-main
entry". This is useful when you would like to inject multiple
dependent files together and graph their dependencies into one
"chunk".
Webpack.config.js
require("babel-polyfill");
var config = {
devtool: 'cheap-module-eval-source-map',
entry: {
main: [
// configuration for babel6
['babel-polyfill', './src/js/main.js']
]
},
}
Alternative to Webpack - load babel-polyfill as an external script in the browser html
The alternative to using webpack would mean including the module as an external script in your html. It will then be available to code in the browser but the webpack bundle won't be directly aware of it.
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.22.0/polyfill.js"></script>

Uncaught ReferenceError: require is not defined webpack with telegram

I am trying to use telegram node modules (telegram-js, telegram-mt-node, telegram-tl-node) inside webpack on a client web app.
currently I am getting this error:
Uncaught ReferenceError: require is not defined
the error is pointing to this line:
module.exports = require("crypto");
I did a global search through my node_modules and "crypto" is only found inside webpack and less node modules, not telegram. I cant find a line anywhere that actually matches the line it references.
In the webpack build file, require() is normally changed to _webpack_require(). So it seems webpack got confused during the build process.
Here is my webpack.config
var path = require('path');
var webpack = require('webpack');
var libraryName = 'webapp';
var version = '1.0';
var config = {
entry: './app-src/proto.index.js',
output: {
path: __dirname+"/build/lib/",
publicPath: "/build/",
filename: libraryName+'.all.js',
library: libraryName,
libraryTarget: 'umd',
umdNamedDefine: true
},
target: 'node',
node: {
fs: 'empty',
net: 'empty',
tls: 'empty',
crypto: 'empty'
},
resolve: {
root: [
path.resolve('./app-src/'),
path.resolve('../cmn/'),
]
},
module: {
loaders: [
{ test: /\.json$/, loader: "json-loader" },
// JS and JSX
{
test: /.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015', 'react'],
retainLines: true
}
},
{
test: /\.(woff|woff2|eot|ttf)$/,
loader: 'file-loader?name=fonts/[name].[ext]'
}
]
},
};
module.exports = config;
telegram-mt-node, telegram-tl-node have both been written with browsify in mind, like making use of requirish for example. I have removed all references to requirish and fixed the require issues webpack had during the build process. The error I am running into is during runtime on the browser.
Any help is appreciated.
It turns out that telegram node_modules were written for browserify not webpack. Switched to the browserify build manager got things going

Categories