Using webpack with require module on client side Javascript in NodeJS application - javascript

I'm trying to follow this tutorial for creating a redux form in my NodeJS application. I put the code in my client side Javascript file and tried to run my application but I got a "require is not defined error". I'm using webpack to compile my Javascript file, which this other post suggested, so I'm not sure how I would go about using the require module on the client side. Is there a step I'm missing in order to be able to use the require module?
These are the lines in my client.js file that are causing the error:
import React, { Component, PropTypes } from 'react'
import { reduxForm } from 'redux-form'
This is what I have in webpack.config.js file:
var webpack = require('webpack');
var path = require('path');
var nodeExternals = require('webpack-node-externals');
var React = require('react');
var redux = require('redux');
var BUILD_DIR = path.resolve(__dirname, 'public');
var APP_DIR = path.resolve(__dirname, 'app');
var config = {
entry: APP_DIR + '/client.js',
output: {
path: BUILD_DIR,
filename: 'bundle.js'
},
target: 'node',
externals: [nodeExternals()],
module: {
loaders: [
{
test: /\.jsx?/,
include: APP_DIR,
loader: 'babel'
}
]
}
};
module.exports = config;

Related

Webpack compiling error if "require('dotenv').config()" is in index.js How can I fix?

require('dotenv').config() cause webpack compiler error:
ERROR in ./node_modules/dotenv/lib/main.js 26:11-24
Module not found: Error: Can't resolve 'os' in 'C:\Users****\node_modules\dotenv\lib'
It seems like webpack can't handle in index.js but I can't understand why.
my webpack.config.js:
const path = require(`path`);
const HtmlWebpackPlugin = require('html-webpack-plugin');
const {CleanWebpackPlugin} = require(`clean-webpack-plugin`);
module.exports = {
watch: true,
mode: `development`,
entry: {
app: `./src/index.js`,
profile: `./src/profile.js`
},
plugins: [
new HtmlWebpackPlugin(),
new CleanWebpackPlugin()
],
output: {
filename: `[name].bundle.js`,
path: path.resolve(__dirname, `dist`)
},
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
],
},
};
index.js
require('dotenv').config()
import "./style.css";
const title = document.createElement("h3");
title.textContent = "Webpack made easy";
document.body.append(title);
title.classList.add("hello");
console.log(process.env.API_KEY);
Please use it in webpack configuration file. (webpack.config.js)
Also, you need to install dotenv-webpack package.
Please look at this link.
https://github.com/mrsteele/dotenv-webpack/blob/master/README.md
Add new Dotenv() to your plugins array

You may need an appropriate loader to handle this file type error occurs in ReactJS file

I have divided my configuration in to two production and development mode and merging them using webpack-merge.
Whenever i try to build or run the code it gives me you may need an appropriate loader error even though i have define loader for the jsx or js files.
Common Config File code is here...
const path = require("path");
const HtmlWebpackPlugin = require('html-webpack-plugin'); //installed via npm
const webpack = require('webpack'); //to access built-in plugins
module.exports = {
entry : "./src/index.js",
module: {
rules: [
{
test: /\.scss$/,
use: [
"style-loader",
"css-loader",
"sass-loader"
]
},
{
test: /.(js|jsx)$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015', 'react']
}
}
]
},
plugins: [
new webpack.ProgressPlugin(),
new HtmlWebpackPlugin({template: './src/index.html'})
]
}
Production Config Code is
const path = require("path");
const common = require("./webpack.config");
const merge = require("webpack-merge");
module.exports = (common, {
mode : "production",
output: {
filename : "bundle.[contentHash].js",
path : path.resolve(__dirname, "dist")
}
});
Development Config Code
const path = require("path");
const common = require("./webpack.config.js");
const merge = require("webpack-merge");
module.exports = (common, {
mode : "development",
output: {
filename : "bundle.js",
path : path.resolve(__dirname, "dist")
}
});
index.js code
import "./assets/scss/main.scss";
import React from 'react';
import ReactDOM from 'react-dom';
class App extends React.Component {
render() {
return <h1>Hello</h1>
}
}
ReactDOM.render(<App/>, document.getElementById('app'));
.babelrc code
{
"presets": ["env", "react","#babel/preset-env"],
"plugins": [
"transform-class-properties"
]
}
You will need to call merge on both your files, merging common with the object specified for each case:
// webpack.prod.js
const path = require("path");
const common = require("./webpack.config");
const merge = require("webpack-merge");
module.exports = merge(common, {
mode : "production",
output: {
filename : "bundle.[contentHash].js",
path : path.resolve(__dirname, "dist")
}
});
// webpack.dev.js
const path = require("path");
const common = require("./webpack.config.js");
const merge = require("webpack-merge");
module.exports = merge(common, {
mode : "development",
output: {
filename : "bundle.js",
path : path.resolve(__dirname, "dist")
}
});
That error occurs because your JSX is not being compiled to JavaScript.
The test in your config file that handles this is:
test: /.(js|jsx)$/,
loader: 'babel-loader',
I see that you've imported "webpack-merge" but it does not appear that you're using it (at least in the code that is displayed in your question).So it seems like you're not merging the disparate config files in the way you're expecting (or maybe at all).
Instead of splitting your config into multiple files, usually [from what I've seen] developers prefer to use one file with some logic in it based on an environmental variable: https://webpack.js.org/guides/environment-variables/
process.env.NODE_ENV === 'dev' ? doDevStuff : doProdStuff

Webpack JSX cannot resolve relative module through ES6 imports

I'm setting up webpack for a large already existing React App.
Seems to be working fine but some modules causes trouble unless I specifically add the extension to the import
//not working
import AppRouter from './router';
//working but meh
import AppRouter from './router.jsx';
It does not occur in all the relative imports but some for what I see look random.
The error, it occur multiple times for different files
ERROR in ./src/main/resources/js/cs/index.js
Module not found: Error: Can't resolve './router' in '<ommited_path>/src/main/resources/js/cs'
# ./src/main/resources/js/cs/index.js
The folder structure for that file
/src
--/main
--/resources
--/js/
--/cs
index.js
router.jsx
store.js
webpack.config.js
const path = require('path');
const webpack = require('webpack');
const paths = require('./config/paths');
const config = {
entry: {
index: path.join(__dirname, paths.custServReactIndex),
},
output: {
path: path.join(__dirname, paths.outputScriptsFolder),
filename: '[name].js',
publicPath: paths.outputScriptsFolder,
},
mode: 'development',
module: {
rules: [
{
// Compile main index
test: /\.jsx?$/,
loader: 'babel-loader',
},
],
},
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
}),
],
};
module.exports = config;
.babelrc
{
"ignore": ["node_modules"],
"presets": ["env", "stage-0", "react"]
}
That being said, any idea on why some relative imports are failing and how can I solve so?
You need to add resolve extensions. Add the below config in Webpack and restart React app
resolve: {
modules: [
path.resolve("./src"),
path.resolve("./node_modules")
],
extensions: [".js", ".jsx"]
}

Uncaught SyntaxError:` Unexpected token import

I am working on a react application. Where I am using webpack and babel loader.
In my react application I am using import statement many times which is working fine.
Now I have My another stand alone application which is working fine.
Now I am installing my standalone application in react application using npm. So I do
let standAloneApplication = require("my_stand_alone_application")
But I get import error inside the standAloneApplication. Where I have a line
import controller from "./controller" // Main.js:1Uncaught SyntaxError: Unexpected token import
where as import statement in React application works fine. also the stand alone application work fine at alone. but together It's giving SyntaxError
my webpack file
var webpack = require('webpack');
var path = require('path');
var BUILD_DIR = path.resolve(__dirname, 'html');
var APP_DIR = path.resolve(__dirname, 'html');
var config = {
entry: APP_DIR + '/app.js',
output: {
path: BUILD_DIR,
filename: 'bundle.js'
},
devtool: "source-map",
node: {
fs: "empty"
} ,
module : {
loaders : [
{
test : /\.js?/,
include : APP_DIR,
exclude: /node_modules/,
loaders: ['babel?presets[]=react,presets[]=es2015,plugins[]=transform-decorators-legacy,plugins[]=transform-class-properties,plugins[]=transform-export-extensions'],
},
{ test: /\.json$/, loader: "json" }
]
}
}
module.exports = config;
main.js Code from stand alone application
import {Controller} from "./Controller/index.js"
export class Main () {
}
Notice the exclude: /node_modules/ in your loader setup.
Since you installed your app/module using npm, it's located in that directory, and because of the exclusion it will not be transpiled by Babel.
Perhaps, but I'm not sure, you can add it explicitly to the include line:
include : [
APP_DIR,
path.resolve(__dirname, 'node_modules/my_stand_alone_application')
]

What is the best practice for importing angularjs using webpack?

How do you use Webpack and AngularJS together, and how about template loading and on demand fetching of resources?
An example of a well written webpack.config.js file for this purpose would be very much appreciated.
All code snippets displayed here can be accessed at this github repo. Code has been generously adapted from this packetloop git repo.
webpack.config.json
var path = require('path');
var ResolverPlugin = require("webpack/lib/ResolverPlugin");
var config = {
context: __dirname,
entry: ['webpack/hot/dev-server', './app/app.js'],
output: {
path: './build',
filename: 'bundle.js'
},
module: {
loaders: [{
test: /\.css$/,
loader: "style!css-loader"
}, {
test: /\.scss$/,
loader: "style!css!sass?outputStyle=expanded"
}, {
test: /\.jpe?g$|\.gif$|\.png$|\.svg$|\.woff$|\.ttf$/,
loader: "file"
}, {
test: /\.html$/,
loader: "ngtemplate?relativeTo=" + path.join(__dirname, 'app/') + "!raw"
}]
},
// Let webpack know where the module folders are for bower and node_modules
// This lets you write things like - require('bower/<plugin>') anywhere in your code base
resolve: {
modulesDirectories: ['node_modules', 'lib/bower_components'],
alias: {
'npm': __dirname + '/node_modules',
'vendor': __dirname + '/app/vendor/',
'bower': __dirname + '/lib/bower_components'
}
},
plugins: [
// This is to help webpack know that it has to load the js file in bower.json#main
new ResolverPlugin(
new ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"])
)
]
};
module.exports = config;
To import AngularJS into the main app.js you do the following:
app/vendor/angular.js
'use strict';
if (!global.window.angular) {
require('bower/angular/angular');
}
var angular = global.window.angular;
module.exports = angular;
And then use it in app.js like so,
app.js
...
var angular = require('vendor/angular');
// Declare app level module
var app = angular.module('myApp', []);
...
Is the following correct? Is there an easier way to do this? I've seen a few (not a lot by any standards) posts which listed another method.
From this reddit post comment
// Add to webpack.config.js#module#loaders array
{
test: /[\/]angular\.js$/,
loader: "exports?angular"
}
There is also another plugin which is in development right now, at stackfull/angular-seed. It seems to be in the right direction, but is really really hard to use right now.
Webpack is way awesome, but the lack of documentation and samples are killing it.
You can just require angular in all modules (files) where you need it. I have a github repository with example how to do that (also using webpack for build). In the example ES6 import syntax is used but it shouldnt matter, you can use standard require() instead.
Example:
import 'bootstrap/dist/css/bootstrap.min.css';
import './app.css';
import bootstrap from 'bootstrap';
import angular from 'angular';
import uirouter from 'angular-ui-router';
import { routing} from './app.config';
import common from './common/common.module';
import featureA from './feature-a/feature-a.module';
import featureB from './feature-b/feature-b.module';
const app = angular
.module('app', [uirouter, common, featureA, featureB])
.config(routing);
I am starting with Angular + Flux with Webpack so may be I can help you with some things.
Basically I am installing everything with NPM, it has module export system, so it works like nothing. (You can use export-loader, but why if you do not need to.)
My webpack.config.js looks like this:
var webpack = require('webpack');
var path = require('path');
var HtmlWebpackPlugin = require("html-webpack-plugin");
var nodeModulesDir = path.resolve(__dirname, './node_modules');
// Some of my dependencies that I want
// to skip from building in DEV environment
var deps = [
'angular/angular.min.js',
...
];
var config = {
context: path.resolve(__dirname, './app'),
entry: ['webpack/hot/dev-server', './main.js'],
resolve: {
alias: {}
},
output: {
path: path.resolve(__dirname, './build'),
filename: 'bundle.js'
},
// This one I am using to define test dependencies
// directly in the modules
plugins: [
new webpack.DefinePlugin({
ON_TEST: process.env.NODE_ENV === 'test'
})
],
module: {
preLoaders: [
{test: /\.coffee$/, loader: "coffeelint", exclude: [nodeModulesDir]}
],
loaders: [
{test: /\.js$/, loader: 'ng-annotate', exclude: [nodeModulesDir]},
{test: /\.coffee$/, loader: 'coffee', exclude: [nodeModulesDir]},
...
],
noParse: []
},
devtool: 'source-map'
};
if (process.env.NODE_ENV === 'production') {
config.entry = {
app: path.resolve(__dirname, './app/main.js'),
vendors: ['angular']
};
// config.output.path = path.resolve(__dirname, './dist');
config.output = {
path: path.resolve(__dirname, "./dist"),
filename: "app.[hash].js",
hash: true
};
config.plugins.push(new webpack.optimize.UglifyJsPlugin());
config.plugins.push(new webpack.optimize.CommonsChunkPlugin('vendors', 'vendors.[hash].js'));
config.plugins.push(new HtmlWebpackPlugin({
title: 'myApp',
template: path.resolve(__dirname, './app/index.html'),
inject: 'body'
}));
delete config.devtool;
}
else {
deps.forEach(function (dep) {
var depPath = path.resolve(nodeModulesDir, dep);
config.resolve.alias[dep.split(path.sep)[0]] = depPath;
config.module.noParse.push(depPath);
});
}
module.exports = config;
My main.js looks like this:
var angular = require('angular');
if(ON_TEST) {
require('angular-mocks/angular-mocks');
}
require('./index.coffee');
And index.coffee containt main angular module:
ngModule = angular.module 'myApp', []
require('./directive/example.coffee')(ngModule)

Categories