Webpack, React-router and React from CDN - javascript

I use Webpack for bundling my React application and react-router for routing. ReactJs is loaded from CDN as external library. I get this error message from react-router and I am not sure if it possible to use React loaded from CDN with other react libraries.
PropTypes.js:8
Uncaught TypeError: Cannot read property 'PropTypes' of undefined(…)
(anonymous function) # PropTypes.js:8
__webpack_require__ # bootstrap 2b8bebf…:19
(anonymous function) # index.js:15
__webpack_require__ # bootstrap 2b8bebf…:19
(anonymous function) # index.jsx:3
__webpack_require__ # bootstrap 2b8bebf…:19
(anonymous function) # bootstrap 2b8bebf…:39
(anonymous function) # bootstrap 2b8bebf…:39
index.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
<title>Experiment</title>
</head>
<body>
<div id="content">
<!-- this is where the root react component will get rendered -->
</div>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react-dom.js"></script>
<!-- include the webpack-dev-server script so our scripts get reloaded when we make a change -->
<!-- we'll run the webpack dev server on port 8090, so make sure it is correct -->
<script src="http://localhost:8090/webpack-dev-server.js"></script>
<!-- include the bundle that contains all our scripts, produced by webpack -->
<!-- the bundle is served by the webpack-dev-server, so serve it also from localhost:8090 -->
<script type="text/javascript" src="http://localhost:8090/assets/main.js"></script>
</body>
</html>
index.jsx
import {Router, Route, useRouterHistory, browserHistory} from 'react-router';
ReactDOM.render(
<h1>hello</h1>, document.getElementById('content')
);
webpack.config.js
var webpack = require('webpack');
var merge = require('webpack-merge');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var NpmInstallPlugin = require('npm-install-webpack-plugin');
const TARGET = process.env.npm_lifecycle_event;
console.log("target event is " + TARGET);
var common = {
cache: true,
debug: true,
entry: './src/script/index.jsx',
resolve: {
extensions: ['', '.js', '.jsx']
},
externals: {
// Adapt React to different environments.
'react': {
commonjs: 'react',
commonjs2: 'react',
amd: 'React',
root: 'React'
}
},
output: {
filename: '[name].js',
sourceMapFilename: '[file].map'
},
module: {
loaders: [{
test: /\.js[x]?$/,
loaders: ['babel-loader?presets[]=es2015&presets[]=react'],
exclude: /(node_modules)/
}, {
test: /\.css$/,
loaders: ['style', 'css']
}, {
test: /\.scss$/,
loaders: ['style', 'css', 'sass']
}, {
test: /\.less$/,
loaders: ['style', 'css', 'less']
}, {
test: /\.woff$/,
loader: "url-loader?limit=10000&mimetype=application/font-woff&name=[path][name].[ext]"
}, {
test: /\.woff2$/,
loader: "url-loader?limit=10000&mimetype=application/font-woff2&name=[path][name].[ext]"
}, {
test: /\.(eot|ttf|svg|gif|png)$/,
loader: "file-loader"
}]
},
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
})
]
};
if(TARGET === 'dev' || !TARGET) {
module.exports = merge(common,{
devtool: 'eval-source-map',
devServer: {
historyApiFallback: false
},
entry: './src/script/index.jsx',
output: {
filename: '[name].js',
publicPath: 'http://localhost:8090/assets'
},
plugins: [
new NpmInstallPlugin({
save: true // --save
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('dev')
})
]
});
}
if (TARGET === 'build') {
module.exports = merge(common, {
devtool: 'source-map',
output: {
path: './dist'
}
});
}
package.json
"dependencies": {
"babel": "^6.5.2",
"babel-core": "^6.18.0",
"babel-loader": "^6.2.7",
"babel-preset-es2015": "^6.18.0",
"babel-preset-react": "^6.16.0",
"bootstrap": "^3.3.7",
"css-loader": "^0.25.0",
"file-loader": "^0.9.0",
"history": "^2.0.1",
"html-webpack-plugin": "^2.24.1",
"http-server": "^0.9.0",
"jquery": "^3.1.1",
"less": "^2.7.1",
"less-loader": "^2.2.3",
"node-sass": "^3.10.1",
"npm-install-webpack-plugin": "^4.0.4",
"react": "^15.3.2",
"react-datagrid": "^2.1.1",
"react-dom": "^15.3.2",
"react-router": "^3.0.0",
"sass-loader": "^4.0.2",
"style-loader": "^0.13.1",
"url-loader": "^0.5.7",
"webpack": "^1.13.3",
"webpack-dev-server": "^1.16.2",
"webpack-merge": "^0.15.0"
}

Can you actually specify the environment like that in externals? The docs seem pretty straightforward on how to use it. This is what my externals looks like, and I use React/ReactDOM from CDN and with other libraries no problem:
externals: {
react: 'React',
'react-dom': 'ReactDOM'
}
It seems to set the environment you need to use the output.library and output.libraryTarget options, specifically the libraryTarget option as shown in the doc examples.

Related

Error: Cannot read property 'PureComponent' of undefined

I am creating a external npm package .My package bundle is successfully created but when I am putting the bundle.js on console it give is this error
Error: Cannot read property 'PureComponent' of undefined
here is my webpack config
const config = {
// TODO: Add common Configuration
mode: "production",
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"
}
]
},
};
const fooConfig = Object.assign({}, config, {
name: "header_react_next",
entry: "./src/index.js",
output: {
path: path.resolve("build"),
libraryTarget: "umd",
library: "header",
filename: `index.js`,
},
externals: {
'react': 'react',
'react-dom': 'react-dom',
},
plugins: [
]
});
module.exports = [
fooConfig
];
it create the bundle but when I am putting that bundle file on console it give me above error
here is my code with bundle.
these are my devdependancs
"devDependencies": {
"#babel/core": "^7.13.1",
"#babel/preset-env": "^7.13.5",
"#babel/preset-react": "^7.12.13",
"babel-loader": "^8.2.2",
"react": "^17.0.1",
"webpack": "^5.24.1",
"webpack-cli": "^4.5.0"
},
"dependencies": {
"axios": "^0.21.1",
"react-input": "^3.2.3"
}
PureComponent is imported from react package.
But in your Webpack config you've declared it as external.
externals: {
'react': 'react',
'react-dom': 'react-dom',
},
This declaration means that Webpack does not need to bundle 'react' and 'react-dom' packages (from your node_modules) into bundle.js and expects those libraries to be pre-loaded in your HTML.
Please update Webpack config to include React and ReactDOM (those variable names are used by default in react and react-dom)
externals: {
'react': 'React',
'react-dom': 'ReactDOM',
},
and include react and react-dom in your HTML (before bundle.js)
<!-- Load React. -->
<script src="https://unpkg.com/react#17/umd/react.production.min.js" crossorigin></script>
<script src="https://unpkg.com/react-dom#17/umd/react-dom.production.min.js" crossorigin></script>
<!-- Load your Webpack bundle -->
<script src="bundle.js"></script>

Webpack Dependency Not Found

I am new to Webpack and am trying to set it up as a bundler for a relatively simple project (some JS and SASS).
The problems are that one of the dependencies is not being found and that the Bootstrap is not being applied.
The error(s) in the console is
Uncaught ReferenceError: Plyr is not defined
http://localhost:8000/static/index.js:58
n http://localhost:8000/static/index.js:1
http://localhost:8000/static/index.js:25
n http://localhost:8000/static/index.js:1
http://localhost:8000/static/index.js:1
http://localhost:8000/static/index.js:1
webpack.config.js
const path = require("path");
var webpack = require('webpack')
var BundleTracker = require('webpack-bundle-tracker')
module.exports = {
entry: { index: path.resolve(__dirname, "static_src", "index.js") },
output: {
path: path.resolve(__dirname, "static_compiled"),
publicPath: "/static/", // Should match Django STATIC_URL
filename: "[name].js", // No filename hashing, Django takes care of this
chunkFilename: "[id]-[chunkhash].js", // DO have Webpack hash chunk filename, see below
},
plugins: [
new BundleTracker({filename: './webpack-stats.json'}),
],
module: {
rules: [
{ test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel-loader'}, // to transform JSX into JS
{ test: /\.scss$/, use: ["style-loader", "css-loader", "sass-loader"]},
{test: /\.css$/, use: ["style-loader", "css-loader"]}
],
},
resolve: {
alias: {
shared: path.resolve(__dirname, 'node_modules', 'bower_components')
},
extensions: ['.js', '.ts', 'jsx', 'tsx']
},
devServer: {
writeToDisk: true, // Write files to disk in dev mode, so Django can serve the assets
}
}
static_src/index.js
import "./sass/main.scss";
import 'bootstrap/dist/css/bootstrap.min.css';
//import "bootstrap/scss/bootstrap.scss";
import 'bootstrap';
import 'jquery';
import 'plyr/dist/plyr.polyfilled.js';
import "./js/custom.js";
import "./js/clean-blog.js";
from package.json
"dependencies": {
"bootstrap": "^4.4.1",
"jquery": "^3.5.1",
"node-sass": "^4.14.0",
"plyr": "^3.5.10",
"popper.js": "^1.16.1",
"sass-lint": "^1.13.1"
},
"devDependencies": {
"#babel/core": "^7.11.6",
"babel": "^6.23.0",
"babel-loader": "^8.1.0",
"css-loader": "^4.3.0",
"little-loader": "^0.2.0",
"react": "^16.13.1",
"sass": "^1.26.11",
"sass-loader": "^10.0.2",
"style-loader": "^1.2.1",
"webpack": "^4.44.1",
"webpack-bundle-tracker": "^1.0.0-alpha.1",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0"
}
static_src/custom.js
const player = new Plyr('#player', {});
// Expose player so it can be used from the console
window.player = player;
from base.html template
<!-- Custom styles for this template -->
<!-- <link href="{% static 'css/clean-blog.min.css' %}" rel="stylesheet"> -->
<!-- <link href="{% static 'css/main.css' %}" rel="stylesheet"> -->
<script src="{% static 'index.js' %}" type="text/javascript"></script>
On a separate note, I am not sure whether I am including the bundle into HTML properly. Should I have a separate CSS and JS inclusion?

Webpack throws "Module parse failed with Unexpected token" error

I get Module parse failed: Unexpected token. You may need an appropriate loader to handle this file type. error, though I already have webpack.js configured to work with ts/tsx files and all the app was working perfectly before I imported environment-dev.ts in ./src/service/transport-service.ts file.
Does any know what's the problem here? All help is very appreciated.
Error:
ERROR in ./src/services/transport-service.ts 5:24
Module parse failed: Unexpected token (5:24)
You may need an appropriate loader to handle this file type.
| import env from '../../environment-dev';
|
> export default abstract class TransportService {
| private static getCompleteUrl(endpoint: string): string {
| return env.baseUrl + env.prefix + endpoint;
# ./src/services/post-service.tsx 3:28-58
# ./src/pages/Post/index.tsx
# ./src/routes.tsx
# ./src/pages/Main/index.tsx
# ./src/components/app/index.tsx
# ./src/index.tsx
Minified app structure
├── environment-dev.ts
├── package.json
├── src
│ ├── services
│ └── transport-service.ts
├── tsconfig.json
├── tslint.json
├── webpack.config.js
└── yarn.lock
package.json devDependencies:
"devDependencies": {
"#babel/core": "^7.0.0-rc.1",
"#babel/plugin-transform-typescript": "^7.0.0-rc.1",
"#babel/preset-env": "^7.0.0-rc.1",
"#babel/preset-react": "^7.0.0-rc.1",
"#commitlint/cli": "^7.0.0",
"#commitlint/config-conventional": "^7.0.1",
"#types/react": "^16.4.12",
"#types/react-dom": "^16.0.7",
"#types/react-router-dom": "^4.3.0",
"awesome-typescript-loader": "^5.2.0",
"babel-loader": "^8.0.0-beta",
"commitizen": "^2.10.1",
"commitlint": "^7.0.0",
"css-loader": "^1.0.0",
"cz-customizable": "^5.2.0",
"extract-text-webpack-plugin": "4.0.0-beta.0",
"html-webpack-plugin": "^3.2.0",
"husky": "^0.14.3",
"node-sass": "^4.9.3",
"sass-loader": "^7.1.0",
"source-map-loader": "^0.2.4",
"standard-version": "^4.4.0",
"style-loader": "^0.22.1",
"tslint": "^5.11.0",
"tslint-config-airbnb": "^5.11.0",
"tslint-loader": "^3.6.0",
"tslint-react": "^3.6.0",
"typescript": "^3.0.1",
"webpack": "^4.16.5",
"webpack-cli": "^3.1.0",
"webpack-dev-server": "^3.1.5"
}
webpack.js:
const path = require('path');
const HtmlWebPackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
mode: 'development',
entry: './src/index.tsx',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
devtool: 'source-map',
devServer: {
contentBase: path.resolve(__dirname, "dist"),
port: 3000,
open: true
},
resolve: {
extensions: [
'.ts',
'.tsx',
'.js'
]
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
'#babel/preset-env',
'#babel/preset-react'
]
}
}
},
{
test: /\.ts?x$/,
enforce: "pre",
loader: 'tslint-loader'
},
{
test: /\.ts?x$/,
loader: 'awesome-typescript-loader'
},
{
enforce: 'pre',
test: /\.js$/,
loader: 'source-map-loader'
},
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
'css-loader',
'sass-loader'
]
})
}
]},
plugins: [
new HtmlWebPackPlugin({
template: './src/index.html',
filename: './index.html'
}),
new ExtractTextPlugin('style.css')
]
};
transport-service.ts:
import axios from 'axios';
import env from '../../environment-dev';
export default abstract class TransportService {
private static getCompleteUrl(endpoint: string): string {
return env.baseUrl + env.prefix + endpoint;
}
public static get(url: string, params: any = {}): Promise<any> {
return axios.get(this.getCompleteUrl(url), { params });
}
public static post(url: string, body: any = {}, params: any = {}): Promise<any> {
return axios.post(env.baseUrl, body, { params });
}
public static put(url: string, body: any = {}, params: any = {}): Promise<any> {
return axios.put(env.baseUrl, body, { params });
}
public static delete(url: string, params: any = {}): Promise<any> {
return axios.delete(env.baseUrl, { params });
}
}
environment-dev.ts:
export default {
baseUrl: 'http://localhost:3001',
prefix: ''
};
It looks like you have the question mark in the wrong place in test: /\.ts?x$/ and the pattern is not matching the .ts extension. Try replacing that with test: /\.tsx?$/.
In my case I included a file from /test in one of my src-Files. This caused the problem because the testfiles were handled differently by jest + bable

Webpack won't output css file when building less [duplicate]

This is my webpack.config.js file:
var ExtractTextPlugin = require('extract-text-webpack-plugin'),
webpack = require('webpack');
module.exports = {
entry: [
'./src/app.js',
],
output: {
path: __dirname + '/../web/js',
filename: 'build.js',
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader')
},
{
test: /\.(png|woff|woff2|eot|ttf|svg)$/,
loader: "url?limit=5000"
}
]
},
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
}),
new ExtractTextPlugin('build.css')
]
}
This is my package.json file:
"dependencies": {
"angular": "^1.6.4",
"babel-core": "^6.25.0",
"babel-loader": "^7.1.1",
"babel-polyfill": "^6.23.0",
"babel-preset-es2015": "^6.24.1",
"bootstrap": "^3.3.7",
"css-loader": "^0.28.4",
"extract-text-webpack-plugin": "^3.0.0",
"file-loader": "^0.11.2",
"jquery": "^3.2.1",
"style-loader": "^0.18.2",
"url-loader": "^0.5.9",
"webpack": "^3.4.1"
}
This is my app.js file:
import 'babel-polyfill';
import $ from 'jquery';
import 'bootstrap/dist/js/bootstrap.js';
import 'bootstrap/dist/css/bootstrap.css';
After trying to start the webpack I get an error.
ERROR in ./node_modules/bootstrap/dist/css/bootstrap.css Module parse failed:
/var/www/dcracks/app/webpack/node_modules/bootstrap/dist/css/bootstrap.css
Unexpected token (7:5) You may need an appropriate loader to handle this file type.
| */
| /*! normalize.css v3.0.3
| MIT License
| github.com/necolas/normalize.css */
| html {
| font-family: sans-serif;
| -webkit-text-size-adjust: 100%;
# ./node_modules/bootstrap/dist/css/bootstrap.css 4:14-42
# ./src/app.js # multi ./src/app.js
I reread already a bunch of material and shoveled a bunch of posts in various forums.
What am I doing wrong?
The signature of ExtractTextPlugin.extract is:
ExtractTextPlugin.extract(options: loader | object)
As there is no second argument, your css-loader is not being used. The most common configuration is to use css-loader to process the CSS files and style-loader as a fallback, which is used when it shouldn't be extracted (the configured loaders are still applied, but instead of being extracted the fallback loader is used).
You can use the rule that is shown in the Readme - Usage.
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: 'css-loader'
})
}

Unexpected token import with Webpack and Babel

I added react-router v4 to my project with Webpack and NodeJS. The app compiled correctly without any error messages in the log, but the browser console gave me this:
Uncaught SyntaxError: Unexpected token import
at Object.<anonymous> (bundle.js:3391)
at __webpack_require__ (bundle.js:556)
at fn (bundle.js:87)
at Object.eval (eval at <anonymous> (bundle.js:1405), <anonymous>:11:25)
at Object.eval (eval at <anonymous> (bundle.js:1405), <anonymous>:24:27)
at eval (eval at <anonymous> (bundle.js:1405), <anonymous>:25:30)
at Object.<anonymous> (bundle.js:1405)
at __webpack_require__ (bundle.js:556)
at fn (bundle.js:87)
at Object.eval (eval at <anonymous> (bundle.js:3379), <anonymous>:12:17)
I think that the problem is in the Webpack configuration. This is my webpack.config.js:
var path = require('path')
var webpack = require('webpack')
var NpmInstallPlugin = require('npm-install-webpack-plugin')
var autoprefixer = require('autoprefixer');
var precss = require('precss');
module.exports = {
devtool: 'cheap-module-eval-source-map',
entry: [
'webpack-hot-middleware/client',
'babel-polyfill',
'./src/index'
],
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/static/'
},
plugins: [
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new NpmInstallPlugin()
],
module: {
preLoaders: [
{
test: /\.js$/,
loaders: ['eslint'],
include: [
path.resolve(__dirname, "src"),
],
}
],
loaders: [
{
loaders: ['react-hot', 'babel-loader'],
include: [
path.resolve(__dirname, "src"),
],
test: /\.js$/,
plugins: ['transform-runtime'],
presets: ['es2015','react']
},
{
test: /\.css$/,
loader: "style-loader!css-loader!postcss-loader"
}
]
},
postcss: function () {
return [autoprefixer, precss];
}
}
Here is my package.json file:
{
"name": "redux-ru-tutorial",
"version": "1.0.0",
"description": "Redux RU tutorial",
"main": "index.js",
"scripts": {
"start": "node server.js"
},
"author": "Yuriy Shipovalov",
"license": "MIT",
"devDependencies": {
"autoprefixer": "^6.3.1",
"babel-core": "^6.4.5",
"babel-eslint": "^4.1.6",
"babel-loader": "^6.2.1",
"babel-plugin-transform-runtime": "^6.4.3",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.3.13",
"babel-preset-stage-0": "^6.3.13",
"css-loader": "^0.23.1",
"eslint": "^1.10.3",
"eslint-loader": "^1.2.1",
"eslint-plugin-react": "^3.16.1",
"express": "^4.13.4",
"npm-install-webpack-plugin": "^2.0.2",
"postcss-loader": "^0.8.0",
"precss": "^1.4.0",
"react-hot-loader": "^1.3.0",
"style-loader": "^0.13.0",
"webpack": "^1.12.12",
"webpack-dev-middleware": "^1.5.1",
"webpack-hot-middleware": "^2.6.4"
},
"dependencies": {
"babel-polyfill": "^6.3.14",
"babel-runtime": "^6.3.19",
"cors": "^2.8.3",
"history": "^4.6.1",
"jquery": "^3.2.1",
"react": "^0.14.6",
"react-dom": "^0.14.6",
"react-redux": "^4.0.6",
"react-redux-router": "0.0.5",
"react-router": "^4.1.1",
"react-router-dom": "^4.1.1",
"redux": "^3.3.1",
"redux-logger": "2.5.2",
"redux-thunk": "1.0.3"
}
}
Here is my index.js file:
import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import {BrowserRouter as Router, Route} from 'react-router-dom'
import App from './containers/App'
import './styles/app.css'
import configureStore from './store/configureStore'
const store = configureStore()
console.log(store.getState())
render(
<Provider store={store}>
<Router>
<Route> path="/" component={App}></Route>
</Router>
</Provider>,
document.getElementById('root')
)
You're attempting to set Babel's plugins and presets directly in the Webpack configuration as part of module.loaders. This is incorrect. You have to pass it as options to the loader. The error is because you're passing the options incorrectly so Babel does not receive the options, and thus does not transpile your code based on the presets and thus the error.
Depending on your Webpack version, try:
Webpack 1.x
Since you have multiple loaders, you cannot set it in the query object. Instead, you are going to have to set your loader options inline:
{
test: /\.js$/,
loaders: ['react-hot', 'babel?presets[]=es2015,presets[]=react?plugins[]=transform-runtime']
}
This will directly pass the loader options to Babel through a query, but since you have two loaders Webpack didn't know which loader to query so you have to do it inline on one loader.
Here's an example from webpack documentation:
module.rules allows you to specify several loaders within your webpack configuration. This is a concise way to display loaders, and helps to maintain clean code. It also offers you a full overview of each respective loader.
In your case, you can:
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: [
'react-hot','babel-loader'
]
}
]
}
Hope this helps.

Categories

Resources