Uncaught ReferenceError: require is not defined Webpack + AngularJS - javascript

There's dozens and dozens of questions like this one, and none have helped because the root cause is always something I'm not doing. I'm making a bundle for the browser with webpack 4.26.1, and I keep getting Uncaught ReferenceError: require is not defined when I open the webapp in the browser no matter what I do.
I'm not using target: 'node'.
I'm not requiring webpack-node-externals.
I'm not explicitly excluding anything from the bundle.
I'm not using noParse.
I even tried explicitly setting target: 'web' even though it's the default just to see if anything somehow changed.
This is the entirety of my webpack.config.json:
const path = require('path');
module.exports = {
mode: 'production',
entry: './src/main/webapp/resources/app/template.core.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'src/main/webapp/resources/dist')
}
};
This is my package.json
{
(...)
"main": "src/main/webapp/template.core.js",
"dependencies": {
"angular": "^1.6.10",
"angular-animate": "^1.6.10",
"angular-route": "^1.6.10",
"angular-sanitize": "^1.6.10",
"angular-upload": "^1.0.13",
"ui-select": "^0.19.8",
"angular-ui-bootstrap": "^2.5.0",
"moment": "2.22.2"
},
"devDependencies": {
"npm": "^5.6.0",
"webpack": "^4.26.1",
"webpack-cli": "^3.1.2",
"jshint": "^2.9.6"
},
"scripts": {
"lint": "jshint src/main/webapp --exclude src/main/webapp/resources/static,src/main/webapp/resources/dist",
"build": "webpack"
},
(...)
}
What am I doing wrong?

For future reference, my issue was something as basic as having the wrong <script> includes in the html, because due to my webpack configurations, the bundles' filenames are different for development and production modes. I am now using html-webpack-plugin to generate the includes, with my template file being an empty file with just a comment so it outputs nothing but the script tags themselves. Here's how it looks in my webpack.config.js:
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
...
plugins: [
new HtmlWebpackPlugin({
template: 'path/to/empty/template',
filename: 'path/to/templated/output'
})
],
...
};

Related

Can't run React app using WebPack because it's looking in the public directory

I'm a backend developer, trying to pick up and run a simple React app, but having some difficulty. Despite several hours of research and ramping up on React/WebPack/etc, I can't figure the below out:
If I just run npm run build && npm run start I get a 404. I eventually figured out this is because it's looking for index.html in the public subdirectory, whereas it lives in the root folder at present.
I moved it into a public folder, and this time it renders an empty page. I figured out this is because the HTML references ./dist/bundle.js. But of course the dist folder is off the root (where index.html used to be, but it's now in public). I did try ../dist/bundle.js, but unsurprisingly this didn't work.
So, I can either have index.html in the root directory, and find a way to get WebPack to find it there, or put it in public and find a way to reference dist/bundle.js.
As an experiment, I manually copied bundle.js into public and updated the script tag, and it seemed to work fine.
I'm sure this is simple to folk who have lived in this stack for a while. I'm including config files below if it helps.
package.json:
{
// <Omitted>
"main": "index.tsx",
"scripts": {
"build": "webpack",
"watch": "webpack --watch",
"start": "webpack serve --open"
},
"dependencies": {
// <Omitted>
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"devDependencies": {
"#types/node": "^17.0.5",
"#types/react-dom": "^17.0.11",
"ts-loader": "^9.2.6",
"typescript": "~4.5.5",
"webpack": "^5.68.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.7.4"
}
}
WebPack.config.js:
"use strict";
const path = require("path");
module.exports = {
entry: "./src/index.tsx",
devServer: {
port: 3000
},
output: {
filename: "bundle.js"
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: "ts-loader"
}
]
},
resolve: {
extensions: [".ts", ".tsx", ".js", ".jsx"]
},
mode: "development",
devtool: "source-map"
};
I'm not convinced this is the "proper" solution, but I got this working by adding the following to my WebPack.config.js:
devServer: {
static: __dirname,
},

What is causing my tsx to render properly without babel in react app?

Recently I tried to make a react app using typescript and webpack, after playing around with the setup, I found out I was able to run my app (display hello world in the browser) without installing any babel installations that I would normally install (babel-loader/core/preset-env).
To give more context, most of my files were .tsx instead of .jsx, and I'm using ES6 syntax, I am aware that my app wasn't able to identify jsx files and I assume it was because I didn't install babel, but that made me wonder why the .tsx files were able to work properly when displayed on the browser, I did need to install the ts-loader and did some configurations in the webpack.config.js file setting .tsx as one of the file extensions to resolve(webpack.config.js is shown below), but that still made me wonder if that was the reason I didn't need babel.
I guess my main confusion is that I always thought babel was needed to interpret jsx, I know that tsx is a different file extension type, but isn't it kind of like a superset of jsx like ts is to js? I'm just curious why my react app that has HTML-like syntax in my components was able to work without installing babel. I also couldn't find any babel installations in node modules folder so looks like no library I used is using babel under the hood.
In my scenario, seems like babel is not needed for tsx rendering, are there any features that babel provides that might make me want to use it? I know babel can translate ES6 to older version javascript but I can also accomplish that with config settings.(I asked this follow up question mainly because I still see some people have it in their typescript react app, also I only just made a text display on the browser, so I'm not sure if I will run into any other issues if I do not have babel installed)
Thanks to anyone who can answer my question.
To give more info , I have my app settings below
tsconfig.json :
{
"compilerOptions": {
"module": "commonjs",
"jsx": "react",
"watch": true,
"target": "es5",
"lib": ["es6","dom"],
"esModuleInterop": true
}
}
webpack.config.js :
'use strict';
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
entry: './src/index.tsx',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.tsx$/,
exclude: /node_modules/,
use: 'ts-loader'
}
]
},
resolve: {
extensions: ['.ts', '.tsx', '.js']
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html'
})
],
devServer: {
contentBase: path.join(__dirname, 'dist'),
port: 9000
},
optimization: {
minimizer: [new UglifyJsPlugin()]
}
};
sample code :
index.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import Header from './Header';
ReactDOM.render(
<h1>
react-typescript
<Header text={'hello world'} />
</h1>,
document.querySelector('#root')
);
Header.tsx :
import React from 'react';
export interface HeaderProps {
text: string;
num?: number;
}
const Header: React.FC<HeaderProps> = ({ text }) => {
return <div>{text}</div>;
};
export default Header;
package.json :
{
"name": "ts-react",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "./node_modules/.bin/webpack",
"build:watch": "./node_modules/.bin/webpack -w",
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack serve --mode development --env development --hot"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"react": "^17.0.1",
"react-dom": "^17.0.1"
},
"devDependencies": {
"#types/node": "^14.14.28",
"#types/react": "^17.0.2",
"#types/react-dom": "^17.0.1",
"html-webpack-plugin": "^5.1.0",
"ts-loader": "^8.0.17",
"typescript": "^4.1.5",
"uglifyjs-webpack-plugin": "^2.2.0",
"webpack": "^5.22.0",
"webpack-cli": "^4.5.0",
"webpack-dev-server": "^3.11.2"
}
}
Pretty much the same as was already commented, ts-loader is going to compile your .ts .tsx files into targeted versions of javascript from your tsconfig. Babel isn't necessary for typescript projects, but can come with some additional features like being able to transpile for specific browser versions, as well as some performance gains because it doesn't actually type check.

Can not access defined exports from the webpack bundle?

I'm trying to compose a webpack bundle from existing js files and use exports from that in both other JS files and occasionally in html script tag. Later add babel to transpile the whole thing to es5, hence commented out section with babel and ts, that btw works fine.
For now I am having a problem with the exports using straight webpack.
Webpack config as as follows:
var path = require('path');
const { updateCommaList } = require('typescript');
module.exports = {
entry: {
'core' : [
'./src/utils.js',
'./src/zdlg.js'
]
},
devtool: 'source-map',
stats: 'verbose',
resolve: {
modules: ['node_modules']
},
resolveLoader: {
extensions: ['.ts', '.tsx'],
mainFields: ['loader', 'main']
},
output: {
filename: '[name].js',
library: "LIB",
libraryTarget: 'var',
path: path.resolve(__dirname, "dist")
},
module: {
}
};
I can bundle files, no errors there. I'm exporting functions using export statement like so:
export function v ...
And in the html file I have
<script src="./core.js"></script>
<script type="module" src="./io.js"></script>
After tinkering for last few days I've figured out couple things.
If I have a single file in the entry section for core object, exports work, in that the LIB variable has property for each exported function and I can call LIB.v() fine.
imports do not work anyway, i.e.
io.js import:
import {v} from './core.js';
Generates an error when loading the page: Uncaught SyntaxError: import not found: v for the line above.
Adding second file to entry causes webpack to override exports from the 1st file. The reason I didn't see any exports initially was that zdlg.js wasn't exporting anything, and LIB had no exports. If zdlg.js exports any functions they are the only ones that show up on the LIB.
So, in the end, I can export functions from a single file, but I thought the whole purpose of the webpack was to allow to compose modules from multiple files.
I'm not sure what am I missing or where I am going wrong, should be very basic stuff...
In case it is important, here's dev dep list too:
"devDependencies": {
"#babel/core": "^7.8.7",
"#babel/preset-env": "^7.8.7",
"babel-loader": "^8.0.6",
"install": "^0.13.0",
"npm": "^6.14.7",
"ts-loader": "^6.2.1",
"typescript": "^3.8.3",
"webpack": "^4.43.0",
"webpack-cli": "^3.3.12",
"webpack-dev-middleware": "^3.7.2",
"webpack-dev-server": "^3.11.0",
"webpack-merge": "^5.0.9"
}
Made it work, although not sure if this is the best way.
Basically, instead of adding multiple entries in the export's entry section, I've created index.js file which reexported all the exports from the files I needed:
require('./src/ut');
require('./src/zd');
export * from './src/ut';
export * from './src/zd'
Entry is now just index.js
entry: {
'core' : 'index.js'
},
Works as intended, but I am not sure why wouldn't webpack automate this, and why would I have to export everything myself...

How to fix the webpack bug: "you may need an appropriate loader to handle this file type." when I useing webpack to load css files

I am leaning webpack. However, here comes a bug that "You may need an appropriate loader to handle this file type.", I have checked the webpack.config.js, it is correct.
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const webpack = require("webpack");
module.exports = {
entry: {
app: './src/main.js',
print: './src/print.js'
},
devtool: 'inline-source-map',
devServer: {
contentBase: 'dist',
hot: true,
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
}]
},
plugins: [
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({
title: 'Output Management'
}),
new webpack.HotModuleReplacementPlugin()
]
};
Additionally, here is my js file and css file:
import './style.css';
body {
background-color: blue;
}
And the console log this:
./src/style.css
Module parse failed: D:\FrontEndWorkSpace\webpack-demo\src\style.css Unexpected token (1:5)
You may need an appropriate loader to handle this file type.
| body {
| background-color: blue;
| }
Additional, I have already installed both style-loader and css-loader, here are my dependencies on my package.json:
"devDependencies": {
"clean-webpack-plugin": "^0.1.16",
"css-loader": "^0.28.4",
"csv-loader": "^2.1.1",
"file-loader": "^0.11.2",
"html-webpack-plugin": "^2.29.0",
"style-loader": "^0.18.2",
"webpack": "^3.4.1",
"webpack-dev-server": "^2.6.1",
"xml-loader": "^1.2.1"
}
EDIT: For some unknown reasons, it's works.
Make sure you have installed the loaders you're trying to use from NPM. You should see them in both your package.json file and in your node_modules folder of the project. If you don't see them, you can install them and save them to your dev dependencies in your terminal:
$ npm install style-loader css-loader --save-dev
Last bit, I've found this YouTube video series extremely helpful in getting started with Webpack 2. It's changed a lot in its first couple of years, so relevant references are tricky to separate from the obsolete ones.
Good luck taming the webpack beast!
EDIT: Removed extra stuff.

How to make webpack, sass and source maps go along in a multi page app?

Here's where I'm now:
package.json:
{
"dependencies": {
"css-loader": "^0.26.0",
"html-webpack-plugin": "^2.24.1",
"node-sass": "^3.13.0",
"sass-loader": "^4.0.2",
"style-loader": "^0.13.1",
"webpack": "^1.13.3"
}
}
webpack.config.js:
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './1.js',
output: {
path: 'dist',
filename: 'bundle.js',
},
module: {
loaders: [
{test: /\.sass$/, loaders: ['style', 'css?sourceMap', 'sass?sourceMap']},
]
},
plugins: [
new HtmlWebpackPlugin,
],
};
1.js:
require('./1.sass');
1.sass:
body
background: #ddd
Then
$ rm -f dist/* && ./node_modules/.bin/webpack
And open http://example.com/dist in Chrome. Then open Developer Tools > Sources > top > webpack:// > . > 1.sass. And there you'll see css code, not sass code. devtool is for js/coffeescript/whatever, if anything. What am I doing wrong?
UPD
From what I can see, sass-loader passes file as a string. And in that case node-sass (libsass) doesn't return source map. But even if given file, the latter returns source map with generated css code, not sass code for some reason. Any workarounds are welcome, even if ugly.
Well, the issue with libsass not generating source maps for inline content seems to be taken care of. It's just that libsass returns source maps with scss code, even if given sass code. So I mistook it for css.

Categories

Resources