Using Babelify to compile React results in React Router being undefined - browserify

I'm using Gulp for my build system, with Browserify for compiling my JS. I had been using Reactify for JSX compilation, but thought I'd switch to Babelify to get some additional ES2015 features. No errors are thrown when compiling, but when I load my site in the browser I get the following error in my JS console:
Uncaught ReferenceError: Router is not defined
The line the error is referring to is:
var React = require('react');
in the main component file that is being loaded on the page.
The places where I am importing React Router are in my App.jsx file (which is the entrypoint for the application) and my routes.jsx file, where I define the routes:
App.jsx
var React = require('react'),
Router = require('react-router'),
routes = require('./routes.jsx');
Router.run(routes, function(Handler, state) {
var routeClasses = '';
for (var i = 1; i < state.routes.length; i++) {
routeClasses += state.routes[i].name + ' ';
}
React.render(<Handler classes={routeClasses.trim()} />, document.getElementById('root'));
});
routes.jsx
var React = require('react');
Router = require('react-router'),
Route = Router.Route,
DefaultRoute = Router.DefaultRoute,
App = require('./_layout/App.jsx'),
Editor = require('./editor/Editor.jsx');
module.exports = (
<Route name="app" path="/" handler={App}>
<DefaultRoute name="editor" handler={Editor} />
</Route>
);
Everything was working fine when using Reactify rather than Babelify. I'm using Gulp for my build process:
gulp.task('js', function() {
var browserify = require('browserify'),
watchify = require('watchify'),
minifyify = require('minifyify'),
babelify = require('babelify');
function bundle() {
b.bundle()
.on('error', function(error){
gutil.log(error);
})
.pipe(source('app.js'))
.pipe(gulp.dest(paths.client.js.build))
.pipe(gulpif(!isStartup, browserSync.stream()));
isStartup = false;
}
var map = isProd ? false : 'app.map.json';
var b = browserify({
cache: {},
packageCache: {},
entries: paths.client.js.dev,
debug: true,
plugin: [watchify]
})
.transform(babelify, {presets: ['es2015', 'react']})
.plugin('minifyify', {
map: map,
output: paths.client.js.build + 'app.map.json',
});
b.on('update', function(){
bundle();
});
b.on('log', gutil.log); // output build logs to terminal
bundle();
});
The working version, using Reactify, simply omits the .transform(babelify...) line and adds transform: reactify to the browserify() initialization code, i.e.
var b = browserify({
cache: {},
packageCache: {},
entries: paths.client.js.dev,
debug: true,
transform: reactify,
plugin: [watchify]
});

It's working with es2015 import X from Y syntax, e.g.
import React from 'react'

Related

run vue3 ssr on cloudflare workers

I'm trying to run a vue ssr app on cloudflare workers.
I generated a new project using wrangler generate test
I installed vue using npm install vue#next and npm install #vue/server-renderer
I edited the index.js file like this:
const { createSSRApp } = require('vue')
const { renderToString } = require('#vue/server-renderer')
const app = createSSRApp({
data: () => ({ msg: 'hello' }),
template: `<div>{{ msg }}</div>`
})
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
async function handleRequest(request) {
const html = await renderToString(app)
return new Response(html, {status: 200})
}
I then used wrangler dev to test it, but when I access the page I get this error:
ReferenceError: __VUE_PROD_DEVTOOLS__ is not defined
at Module.<anonymous> (worker.js:8:104768)
at n (worker.js:1:110)
at Object.<anonymous> (worker.js:8:104943)
at n (worker.js:1:110)
at worker.js:1:902
at worker.js:1:912
Any help or guidance is appreciated
I faced similar issue and was able to fix it by defining a global constant (VUE_PROD_DEVTOOLS = false) during compile time.
Here is how my webpack prod config looks like:
const webpack = require('webpack');
const { merge } = require("webpack-merge");
const webpackCommon = require("./webpack.common");
const prodConfig = {
mode: 'production',
plugins: [
new webpack.DefinePlugin({
__VUE_PROD_DEVTOOLS__: JSON.stringify(false)
}),
]
};
module.exports = merge(webpackCommon, prodConfig);

Testing nuxt + vue + markdown

I have a new Nuxt project and I'm using markdownit for some pages with <template lang="md">. The project builds and renders fine, but when I try to write jest tests for it, the markdown pages don't get parsed by the proper loader.
Here's a markdown page:
<template lang="md">
# About Us
...
</template>
My test setup in tests/pages.spec.js:
let nuxt = null
beforeAll(async () => {
const config = {
dev: false,
rootDir: resolve(__dirname, '..')
}
nuxt = new Nuxt(config)
await new Builder(nuxt).build()
await nuxt.server.listen(4000, 'localhost')
}, 30000)
// Close server and ask nuxt to stop listening to file changes
afterAll(() => {
nuxt.close()
})
describe('Main page', () => {
// Init Nuxt.js and create a server listening on localhost:4000
// Example of testing only generated html
test('Route / exits and render HTML', async () => {
const context = {}
const { html } = await nuxt.server.renderRoute('/', context)
expect(html).toContain('About Us')
})
My nuxt.config.js has this:
buildModules: [
// Doc: https://github.com/nuxt-community/eslint-module
'#nuxtjs/eslint-module',
'#nuxtjs/vuetify',
'#nuxtjs/markdownit',
'nuxt-responsive-loader', // process image srcsets
],
When I run jest, I get this kind of error:
Nuxt build error
ERROR in ./pages/about.vue?vue&type=template&id=fd87bea8&lang=md& (./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options!./pages/about.vue?vue&type=template&id=fd87bea8&lang=md&)
Module Error (from ./node_modules/vue-loader/lib/loaders/templateLoader.js): (Emitted value instead of an instance of Error)
Errors compiling template:
Component template requires a root element, rather than just text.
1 |
|
2 | # About Us
| ^^^^^^^^^^
It seems like vue-loader is processing it, but in the jest context it's not adding markdownit-loader to process the markdown the way it does when building or running the dev server.

How do you enable source maps in Webpack?

I want to enable source maps in my webpack.config.js. I'm adding onto some opensource and their webpack.config.js looks weird.
webpack.config.js
// Entry point webpack config that delegates to different environments depending on the --env passed in.
module.exports = function(env) {
process.env.NODE_ENV = env;
return require(`./webpack.${env}.js`);
};
Here is what it returns if env = development
/**
* Webpack configuration for development.
*
* Contains plugins and settings that make development a better experience.
*/
const webpack = require("webpack");
const merge = require("webpack-merge");
const fs = require("fs");
const { execSync } = require("child_process");
const path = require("path");
const argv = require("yargs").argv;
const commonConfig = require("./webpack.common.js");
const DashboardPlugin = require("webpack-dashboard/plugin");
const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin");
if (!fs.existsSync(path.resolve(__dirname, "vendor", "vendor-manifest.json"))) {
// This _should_ exist, since we run the command for you when you run `npm run dev`
console.log(
"Vendor files not found. Running 'npm run build:dev-dll' for you..."
);
execSync("npm run build:dev-dll");
console.log("Done generating vendor files.");
}
const devConfig = {
mode: "development",
main: {
devtool: "source-map",
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify("development")
}),
new webpack.DllReferencePlugin({
context: ".",
manifest: require("./vendor/vendor-manifest.json")
}),
new ForkTsCheckerWebpackPlugin({
tslint: true,
async: false,
silent: true
})
]
}
};
// Only enable the dashboard plugin if --watch is specified
// The dashboard plugin annoyingly doesn't allow webpack to exit,
// so we only enable it with --watch, which doesn't exit anyways
if (argv.watch) {
devConfig.main.plugins.push(new DashboardPlugin());
}
module.exports = merge.multiple(commonConfig, devConfig);
I don't know if source map should be added to webpack.config.js or maybe just the development version and I don't know how to add it cause these config files look odd to me.
The line... "devtool": "source-map" is correct, but it appears to be at the wrong depth.
Should be:
const devConfig = {
mode: "development",
devtool: "source-map",
main: {
...
}
};

Mocha test React-Native throws ReferenceError: __DEV__ is not defined

I'm using Atom and the Mocha Test Runner. I'm getting ReferenceError: DEV is not defined when I try to run a test against React-Native (0.33)
The DEV variable is referenced in various react-native core modules.
My mocha test runner options are:
--compilers js:babel-register --opts test/mocha.opts --harmony-proxies test/setup.js
My setup.js looks like this
import chai from "chai";
import fs from 'fs';
import path from 'path';
import register from 'babel-core/register';
import chaiEnzyme from 'chai-enzyme';
const modulesToCompile = [
'react-native',
'react-native-tabs',
'react-native-vector-icons',
'react-native-mock',
'react-native-parallax-scroll-view'
].map((moduleName) => new RegExp(`/node_modules/${moduleName}`));
function getBabelRC() {
var rcpath = path.join(__dirname, '..', '.babelrc');
var source = fs.readFileSync(rcpath).toString();
return JSON.parse(source);
}
var config = getBabelRC();
config.ignore = function(filename) {
if (!(/\/node_modules\//).test(filename)) {
return false;
} else {
const matches = modulesToCompile.filter((regex) => regex.test(filename));
const shouldIgnore = matches.length === 0;
return shouldIgnore;
}
}
register(config);
global.__DEV__ = true;
global.expect = chai.expect;
chai.use(chaiEnzyme());
require('react-native-mock/mock');
const React = require('react-native')
React.NavigationExperimental = {
AnimatedView: React.View
};
Any idea how to deal with this?
It looks like I had deleted a parameter in the Mocha setup, it should be
--compilers js:babel-register --opts test/mocha.opts --harmony-proxies --require test/setup.js

how to use the exclude in browserify?

in browserify-handbook, exclude part,it gives an example of using the exclude:
$ npm install jquery
$ browserify -r jquery --standalone jquery > jquery-bundle.js
then we want to just require('jquery') in a main.js:
var $ = require('jquery');
$(window).click(function () { document.body.bgColor = 'red' });
defering to the jquery dist bundle so that we can write:
<script src="jquery-bundle.js"></script>
<script src="bundle.js"></script>
and not have the jquery definition show up in bundle.js, then while compiling the main.js, you can --exclude jquery:
browserify main.js --exclude jquery > bundle.js
but when i try to run this sample,i got an error of "Uncaught Error: Cannot find module 'jquery'"
i know if i use standalone,i can just use 'jquery' as a global variable, but it's not modular, so i still want to do as the sample using "require('jquery')", so,what shall i do to achieve it?
I finally got this functionality working using information found here:
https://truongtx.me/2014/03/20/browserify-bring-nodejs-modules-to-browser/
I wonder if the docs you found are out of date now...
The working solution in the above link uses the '-x' option ('external') rather than the '-u' option ('exclude')
The linked article also demonstrates how to set this up using gulp.
I'm pasting the relevant content from the above-linked web site:
$ browserify -r foo.js > foo-out.js
$ browserify -r d3-browserify > d3-browserify-out.js
For main.js
$ browserify -x ./foo.js -x d3-browserify main.js > main-bundle.js
In the browser, you need to include all those 3 files
<script src="foo-out.js"></script>
<script src="d3-browserify-out.js"></script>
<script src="main-bundle.js"></script>
Update: The link I posted does not seem to be working so I'm including my current gulpfile.js. I'm new to gulp and javascript, so there may be a better way to do this stuff. But this current setup does basically work:
var browserify = require('browserify');
var gulp = require('gulp');
var watchify = require('watchify');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');
var jshint = require('gulp-jshint');
var uglify = require('gulp-uglify');
var sourcemaps = require('gulp-sourcemaps');
var gutil = require('gulp-util');
var del = require('del');
const PATH_OPTS = {
src_dir: './client/js/src/',
main_file_path: './client/js/src/main.js',
output_file_name: 'disco.js',
output_dir: './public/js/',
common_lib_file_name: 'common.js'
};
const LIBS = ['paper', 'jquery', 'tocktimer'];
gulp.task("clientlib", function() {
var bundler = browserify({
debug: false
});
LIBS.forEach(function(lib) {
bundler.require(lib);
});
bundler.bundle()
.pipe(source(PATH_OPTS.common_lib_file_name))
// uglify seems to need a buffered stream...
.pipe(buffer())
.pipe(uglify())
.on('error', gutil.log)
.pipe(gulp.dest(PATH_OPTS.output_dir));
});
gulp.task('client', function () {
var bundler = browserify({
debug: true,
cache: {},
packageCache: {},
fullPaths: true
});
bundler = watchify(bundler);
bundler.on('update', function(){
bundle(bundler);
});
bundler.on('log', function(msg) {
gutil.log(msg);
});
bundler.add(PATH_OPTS.main_file_path);
LIBS.forEach(function(lib) {
bundler.external(require.resolve(lib, { expose: lib }));
});
return bundle(bundler);
});
function bundle(bundler) {
return bundler.bundle()
.pipe(source(PATH_OPTS.output_file_name))
.pipe(buffer())
.pipe(sourcemaps.init({loadMaps: true}))
// Add transformation tasks to the pipeline here.
.pipe(uglify())
.on('error', gutil.log)
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest(PATH_OPTS.output_dir));
}
gulp.task('lint', function() {
return gulp.src(PATH_OPTS.src_dir + '*.js')
.pipe(jshint())
.pipe(jshint.reporter('default'));
});
gulp.task('clean', function () {
return del([
PATH_OPTS.output_dir + '/*.*'
]);
});
gulp.task('full', ['lint', 'clean', 'clientlib', 'client']);
gulp.task('default', ['lint', 'client']);