React ES6 SystemJS - Uncaught (in promise) Error: Unexpected token <(…) - javascript

I have react and react-dom installed and imported in via the System.config below, but I still get this error below:
Uncaught (in promise) Error: Unexpected token <(…)
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ES2015 Module Example</title>
</head>
<body>
<script src="lib/system.js"></script>
<script>
System.config({
"baseURL": "src",
// Set defaultJSExtensions to true so you don't have to use .js extension when importing the es6 module.
"defaultJSExtensions": true,
// 'plugin-babel' or 'traceur' or 'typescript'
transpiler: 'traceur',
map: {
'react': './node_modules/react/dist/react.min.js',
'react-dom': './node_modules/react-dom/dist/react-dom.min.js',
'traceur': './lib/traceur.min.js',
'plugin-babel': './lib/plugin-babel/plugin-babel.js',
'systemjs-babel-build': './lib/plugin-babel/systemjs-babel-browser.js'
},
});
System.import("app.js");
</script>
</body>
<div id="example"></div>
</html>
app.js:
import React from 'react';
import ReactDOM from 'react-dom';
var Hello = React.createClass({
render: function() {
return <h1>Hello {this.props.name}</h1>;
}
});
ReactDOM.render(
<Hello name="World" />,
document.getElementById('example')
);
Any ideas what else do I have to configure?

browserify is the best solution (for production & development) - to me:
npm install --save-dev babel-preset-react
gulp:
var gulp = require('gulp');
var browserify = require('browserify');
var babelify = require('babelify');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');
var uglify = require('gulp-uglify');
var sourcemaps = require('gulp-sourcemaps');
var livereload = require('gulp-livereload');
gulp.task('build', function() {
// app.js is your main JS file with all your module inclusions
return browserify({entries: 'src/app.js', debug: true})
.transform("babelify", { presets: ["es2015", "react"] })
.bundle()
.pipe(source('compile.min.js'))
.pipe(buffer())
.pipe(sourcemaps.init())
.pipe(uglify())
.pipe(sourcemaps.write('./maps'))
.pipe(gulp.dest('js'))
.pipe(livereload());
});
gulp.task('default', ['build']);
As for non-production with SystemJS (painfully slow):
<!DOCTYPE html>
<script src="https://jspm.io/system#0.19.js"></script>
<script>
System.config({
transpiler: 'babel',
babelOptions: {}
});
System.import('./main.js');
</script>
You still can use gulp for development. Just add this to the gulpfile:
gulp.task('watch', ['build'], function () {
livereload.listen();
gulp.watch('js/*.js', ['build']);
});
gulp.task('default', ['watch']);
This saves you from other tedious dev workflows as listed here.

Unexpected token < usually occurs in html5 applications, when the server is configured to return the contents of index.html instead of 404 pages (so pressing f5 on dynamic routing still works). Check then network panel in your browsers developer console, and see which js file was served with html contents.

Related

Vue CLI 3 prerender-spa-plugin

I've tried to prerender the routes of my SPA with the npm package prerender-spa-plugin with Vue CLI 3, and I get a decent output as seen here after running "npm run build":
The output in the index.html is an error:
<html>
<head>
</head>
<body>Html Webpack Plugin:
<pre> ReferenceError: BASE_URL is not defined
- index.html:96
C:/Users/Fred/v2/public/index.html:96:11
- index.html:99 0971.module.exports
C:/Users/Fred/v2/public/index.html:99:3
- index.js:284 Promise.resolve.then
[v2]/[html-webpack-plugin]/index.js:284:18
</pre>
</body>
</html>
My vue.config.js is this:
const path = require('path');
const PrerenderSPAPlugin = require('prerender-spa-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
configureWebpack: {
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html',
inject: false
}),
new PrerenderSPAPlugin({
staticDir: path.join(__dirname, './dist'),
routes: ['/', '/om-guldbaek', '/om/:id', '/aktiviteter', '/aktivitet/:id', '/foreninger', '/forening/:id', '/begivenheder', '/begivenhed/:id', '/gdpr', '/institutioner', '/institution/:id', '/login', '/nyheder', '/nyhed/:id', '/kontakt', '/registreringer'],
})
],
},
};
When I run "npm run build" in VSCode, it keeps returning "Building for production..." without anything happening. Anyone know about this issue?
Alright I found the issue. In the index.html I had the line:
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
So now it's fixed

Dynamically load/import split vendor chunks/bundles via Webpack

I have a simple sample application that is structured thusly:
/dist
index.html
app.bundle.js
moduleA.bundle.js
moduleB.bundle.js
vendors~app~moduleA~moduleB.bundle.js
[...sourcemaps]
/node_modules
[...]
/src
index.js
moduleA.js
moduleB.js
package.json
webpack.config.js
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test Dependency Pulls</title>
</head>
<body>
<script type="text/javascript" src="app.bundle.js"></script>
</body>
</html>
src/index.js
import _ from 'Lodash';
import printA from './moduleA.js';
import printB from './moduleB.js';
function component() {
var element = document.createElement('div');
var btn = document.createElement('button');
element.innerHTML = _.join(['Hello', 'webpack', '4'], ' ');
btn.innerHTML = 'printA. Click me and check the console.';
btn.onclick = printA;
element.appendChild(btn);
btn = document.createelement('button');
btn.innerHTML = 'printB. Click me and check the console.';
btn.onclick = printB;
element.appendChild(btn);
return element;
}
document.body.appendChild(component());
src/moduleA.js
import printB from './moduleB.js';
export default function printA() {
console.log('AAA I get called from moduleA.js!');
}
src/moduleB.js
import _ from 'Lodash';
export default function printB() {
console.log('BBB I get called from moduleB.js!');
}
/webpack.config.js
const path = require('path');
module.exports = {
mode: 'development',
devtool: 'source-map',
entry: {
app: './src/index.js',
moduleA: './src/moduleA.js',
moduleB: './src/moduleB.js',
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
},
optimization: {
splitChunks: {
chunks: 'all'
}
}
}
When I pull in app.bundle.js, I expect the vendor bundle to be auto-pulled as well, since it is a dependency for app.js. Currently, this is not happening - the vendor bundle is not loaded. I'm not even seeing an attempt in the network tab.
How do I tell webpack to automatically load dependencies of a bundle?
Webpack bundling/dependency management does not work exactly in that way. You need to manually add a <script> tag to the html for each bundle (entry).
However, you may want to look into using:
html-webpack-plugin:
https://www.npmjs.com/package/html-webpack-plugin
https://webpack.js.org/plugins/html-webpack-plugin
which will automatically inject the bundle references to your html.
html-webpack-template:
https://github.com/jaketrent/html-webpack-template
may also help with additional customization/features.

browserify bundle doesn't handle importing files via relative path

I am using browserify and babel to compile and bundle my react app. The files from client/ are bundled up into a single file static/bundle.js. But I use a relative import which seems to not be handled correctly.
Here's my file structure
client/
components/
main.js
App.js
static/
bundle.js
gulpfile.js
and here's my gulpfile and the offending import
// client/App.js
import React, { Component } from 'react';
import { render } from 'react-dom';
import App from './components/main.js';
render(
<App />,
document.getElementById('root'),
);
// gulpfile.js
var gulp = require('gulp');
var browserify = require('browserify');
var babelify = require('babelify');
var source = require('vinyl-source-stream');
gulp.task('build', function() {
browserify({
entries: 'client/App.js',
extensions: ['.js'],
debug: true
})
.transform(babelify, {presets: ['es2015', 'react']})
.bundle()
.pipe(source('bundle.js'))
.pipe(gulp.dest('static'));
});
The problem is the line import App from './components/main.js';.
When I look in static/bundle.js, there is a line var _main = require('./components/main.js');, which doesn't make sense because relative to bundle.js there is no ./components/main.js. That was defined relative to client/App.js.
Does browserify not handle such things and is there another tool I should be using in addition, or am I doing something else incorrect?
You have to add paths to your browserify options. If you do not add that browserify doesn't know where to look for to find your module.
module.exports = function(grunt){
grunt.initConfig({
browserify: {
options:{
browserifyOptions: {
// ...
paths: [
'./node_modules',
'./client'
]
}
},
// ...
},
// ...
});
}
This was an issue before they solve it.

Browserify failing to compile react

This is the gulpfile.js:
var gulp = require('gulp'),
browserify = require('gulp-browserify'),
babel = require('gulp-babel'),
babelify = require("babelify");
gulp.task('js', function () {
gulp.src(config.paths.js.src)
.pipe(browserify({
insertGlobals : true,
debug : true
}))
.pipe(gulp.dest(config.paths.js.dest))
});
In package.json I have added:
"browserify": {
"transform": [["babelify", { "presets": ["react"] }]]
}
And this is the file with react:
ReactDOM.render(
<Overlay message="TEST" />,
document.getElementById('content')
);
finally, the error is:
components/main-component.js:15
<div class="overlay">
^
ParseError: Unexpected token
at wrapWithPluginError (/home/novak/Documents/myProjects/OpenWorld/node_modules/gulp-browserify/index.js:44:1
Note: I am not using ES2015, just normal js.
I have tried a lot of things to put into the gulp task, but it always gives me some error. Could anybody advise me how to make this work please?
Some more sources:
main-component.js:
var React = require('react');
var ReactDOM = require('react-dom');
var Print = require('./main-template');
var Overlay = React.createClass({
getInitialState: function() {
return { show: false };
},
render: function() {
if (!this.state.show) {
return;
}
return(
<div class="overlay">
<div class="content">
<Print message="{this.props.message}"/>
</div>
</div>
);
}
});
ReactDOM.render(
<Overlay message="TEST" />,
document.getElementById('game-content')
);
module.exports = Overlay;
You need to convert .jsx to .js since Browser don't know the JSX. So you need to transform it before.
Steps to covert jsx to js:
Make sure that you have installed
gulp-babel
babel-plugin-transform-react-jsx
by
npm install gulp-babel babel-plugin-transform-react-jsx
Then in your gulp file
var gulp = require('gulp');
var babel = require('gulp-babel');
gulp.task("babel", function(){
return gulp.src("src to jsx/*.jsx").
pipe(babel({
plugins: ['transform-react-jsx']
})).
pipe(gulp.dest("src to js/*.js"));
});

Requirejs not loading a jquery plugin

I'm working on improving the tests for jquery-csv (jquery plugin).
I can currently run a full suite of tests (ie mocha/chai) from the command line with no problems. I'm having issues figuring out how to use require.js to load dependencies so I can extend the test runner to work with mochaphantomjs tests.
The HTML used to load RequireJS:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Mocha Tests</title>
<link rel="stylesheet" href="../node_modules/mocha/mocha.css" />
</head>
<body>
<div id="mocha"></div>
<script data-main="scripts/app" src="scripts/require.js"></script>
</body>
</html>
The RequireJS module:
require.config({
baseUrl: '/',
paths: {
'jquery' : '../../node_modules/jquery/dist/jquery',
'jquery-csv' : '../../src/jquery.csv',
'mocha' : '../../node_modules/mocha/mocha',
'chai' : '../../node_modules/chai/chai',
},
shim: {
'mocha': {
exports: 'mocha'
},
'chai': {
exports: 'chai'
},
'jquery-csv' : {
deps: ['jquery'],
exports: 'jQuery.fn.csv',
}
},
});
define(function(require) {
require('jquery');
require('jquery-csv');
// chai setup
var chai = require('chai');
var expect = chai.expect();
var should = chai.should();
// mocha setup
var mocha = require('mocha');
mocha.setup('bdd');
mocha.reporter('html');
mocha.bail(false);
require(['test.js'], function(require) {
if (window.mochaPhantomJS) {
mochaPhantomJS.run();
}
else {
mocha.run();
}
});
});
Note: The define function is using the CommmonJS style.
The error I'm getting is:
Uncaught Error: Module name "../src/jquery.csv.js" has not been loaded yet for context: _. Use require([])
AFAIK, the shim should have fixed this issue by loading jQuery first and attaching the plugin to it.
I'm pretty new to RequireJS, is there something obvious I'm missing?
Try to add your "jquery-csv" as dependency in:
require(['test.js', 'jquery', 'jquery-csv'], function(require, $) {
if (window.mochaPhantomJS) {
mochaPhantomJS.run();
}
else {
mocha.run();
}
});

Categories

Resources