I am a beginner to node js and angular js.
I have a string which is html text and i want to convert it to jade.
I can do this with node js module 'html2jade' but when I am writing my code in js file (in controller), it is giving me a 'require' is not defined error.
This is the code:
app.controller('comicController', function($scope, resources) {
$scope.searchComic = function() {
resources.routes.charactersAPI.fetch({title: $scope.title}, function done(response) {
console.log(response);
$scope.comic = response;
//$scope.comic.description
require('html2jade').convertHtml($scope.comic.description, {}, function (err, jade) {
$scope.desc = jade;
});
});
};
});
Any help is appreciated. Thanks in advance!
You require a module on your build process.
Browsers don't have the require method defined, but Node.js does. With Browserify you can write code that uses require in the same way that you would use it in Node.
Install browserify
npm install -g browserify
Write a module
// hello.js
module.exports = function(name) {
return 'Hello ' + name + '!';
}
Use the module
// app.js
var greetings = require('./hello');
alert(greetings('Christophe'));
Create the bundle
browserify app.js -o bundle.js
Refer your bundle
<html>
<body>
<script src="bundle.js"></script>
</body>
</html>
Browserify is a tool that lets you bundle node.js modules and consume them in the browser. In other words, it allows you to write browser-based applications using node.js-style requires.
You can check here for reference.
Related
I am trying browserify for first time with my express app. I have installed browserify globally. I am getting the error mentioned in subject. I have looked this over several times and all looks correct. I'm thinking maybe something w/browserify and express. My setup is
app.use(express.static(path.join(__dirname, 'public')));
I used this command to install browserify
browserify public/javascripts/main.js -o public/javascripts/bundle.js
My directory structure is
root
---public
---javascripts
bundle.js
main.js
and my ejs
<script src="javascripts/bundle.js"></script>
<script src="javascripts/main.js"></script>
which are 200 ok.
And my main.js contains line
let helper_functions = require('./library/helper_functions');
Is there something I've missed. All docs point to this is how you do it. Any guidance much appreciated.
Update: I just want clarify if Im exported several functions in helper_function.js it can be done like:
let helper_functions =
function strToNumberArray(str, separator = ',') {
// function stuff
}
// Function to convert string to an array then convert each element to a number
// ========================================================================================== //
function strToNumberArray(str, separator = ',') {
function stuff//
}
module.export = helperFunctions;
Consider the following example code (and maybe I am doing it wrong?)
var FlareCurrency = {
};
export {FlareCurrency};
I have the following task:
gulp.task("compile:add-new-currency-minified", function(){
return gulp.src('src/add-new-currency/**/*.js')
.pipe(babel())
.pipe(concat('Flare-AddNewCurrency.js'))
.pipe(uglify({"preserveComments": "all"}))
.pipe(gulp.dest('dist/minified/'));
});
When I run this I get the following:
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var FlareCurrency={};exports.FlareCurrency=FlareCurrency;
For the fun of it, I wanted to run it in the console, yes I know it does nothing but I didn't expect to see this:
Uncaught ReferenceError: exports is not defined(…)
The non minified version:
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var FlareCurrency = {};
exports.FlareCurrency = FlareCurrency;
throws the same error. Ideas?
That is not actually a babel issue, you are just trying to run CommonJS code (transpiled from ES6 export) in the browser without preparation. CommonJS doesn't run on the browser, you need to use a tool to package it for the browser, such as Webpack or Browserify.
Just by coincidence this week I created a small project on Github that shows a setup of Gulp + ES6 code (using export) + Babel + Webpack: gulp-es6-webpack-example.
In my example you can load JS code on the browser either synchronously (pre-loaded) or asynchronously (lazy-loaded).
I fix it just set se6 for settings gulp-typescript package:
import gulp from 'gulp';
import ts from 'gulp-typescript';
import uglify from 'gulp-uglify';
import browserSync from 'browser-sync';
export const scripts = () => {
return gulp.src(['app/scripts/*', '!app/scripts/modules/'])
.pipe(ts({
noImplicitAny: true,
target: "es6" // <<< THIS
}))
.pipe(uglify())
.pipe(gulp.dest('dist/scripts/'))
.pipe(browserSync.stream())
}
Besides you have to set type="module" for connect your js file in html.
<script type="module" src="scripts/index.js"></script>
Consider the following example code (and maybe I am doing it wrong?)
var FlareCurrency = {
};
export {FlareCurrency};
I have the following task:
gulp.task("compile:add-new-currency-minified", function(){
return gulp.src('src/add-new-currency/**/*.js')
.pipe(babel())
.pipe(concat('Flare-AddNewCurrency.js'))
.pipe(uglify({"preserveComments": "all"}))
.pipe(gulp.dest('dist/minified/'));
});
When I run this I get the following:
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var FlareCurrency={};exports.FlareCurrency=FlareCurrency;
For the fun of it, I wanted to run it in the console, yes I know it does nothing but I didn't expect to see this:
Uncaught ReferenceError: exports is not defined(…)
The non minified version:
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var FlareCurrency = {};
exports.FlareCurrency = FlareCurrency;
throws the same error. Ideas?
That is not actually a babel issue, you are just trying to run CommonJS code (transpiled from ES6 export) in the browser without preparation. CommonJS doesn't run on the browser, you need to use a tool to package it for the browser, such as Webpack or Browserify.
Just by coincidence this week I created a small project on Github that shows a setup of Gulp + ES6 code (using export) + Babel + Webpack: gulp-es6-webpack-example.
In my example you can load JS code on the browser either synchronously (pre-loaded) or asynchronously (lazy-loaded).
I fix it just set se6 for settings gulp-typescript package:
import gulp from 'gulp';
import ts from 'gulp-typescript';
import uglify from 'gulp-uglify';
import browserSync from 'browser-sync';
export const scripts = () => {
return gulp.src(['app/scripts/*', '!app/scripts/modules/'])
.pipe(ts({
noImplicitAny: true,
target: "es6" // <<< THIS
}))
.pipe(uglify())
.pipe(gulp.dest('dist/scripts/'))
.pipe(browserSync.stream())
}
Besides you have to set type="module" for connect your js file in html.
<script type="module" src="scripts/index.js"></script>
I have an existing application where I have AMD modules defined using RequireJS. I use "text" and "i18n" plugins for requirejs extensively in my project.
I have been experimenting with ES6 modules lately and would like to use them while creating new modules in my application. However, I want to reuse the existing AMD modules and import them while defining my ES6 modules.
Is this even possible? I know Traceur and Babel can create AMD modules from ES6 modules, but that only works for new modules with no dependency on existing AMD modules, but I could not find an example of reusing the existing AMD modules.
Any help will be appreciated. This is a blocker for me right now to start using all ES6 goodies.
Thanks
Yes, it can be done. Create a new application with the following structure:
gulpfile.js
index.html
js/foo.js
js/main.es6
node_modules
Install gulp and gulp-babel. (I prefer to install gulp locally but you may want it globally: that's up to you.)
index.html:
<!DOCTYPE html>
<html>
<head>
<title>Something</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.20/require.js"></script>
<script>
require.config({
baseUrl: "js",
deps: ["main"]
});
</script>
</head>
<body>
</body>
</html>
gulpfile.js:
"use strict";
var gulp = require('gulp');
var babel = require('gulp-babel');
gulp.task("copy", function () {
return gulp.src(["./js/**/*.js", "./index.html"], { base: '.' })
.pipe(gulp.dest("build"));
});
gulp.task("compile-es6", function () {
return gulp.src("js/**/*.es6")
.pipe(babel({"modules": "amd"}))
.pipe(gulp.dest("build/js"));
});
gulp.task("default", ["copy", "compile-es6"]);
js/foo.js:
define(function () {
return {
"foo": "the value of the foo field on module foo."
};
});
js/main.es6:
import foo from "foo";
console.log("in main: ", foo.foo);
After you've run gulp to build the application, open the file build/index.html in your browser. You'll see on the console:
in main: the value of the foo field on module foo.
The ES6 module main was able to load the AMD module foo and use the exported value. It would also be possible to have a native-AMD module load an ES6 module that has been converted to AMD. Once Babel has done its work, they are all AMD modules as far as an AMD loader is concerned.
In addition to #Louis's answer, assuming you already have a bunch of third party libraries specified in require.js configuration, in your new ES6 modules, whenever you are importing a module, be it amd or es6, you'll be fine as long as you keep the imported module name consistent. For example:
Here is the gulpfile:
gulp.task("es6", function () {
return gulp.src("modules/newFolder//es6/*.js")
.pipe(babel({
"presets": ["es2015"],
"plugins": ["transform-es2015-modules-amd"]
// don't forget to install this plugin
}))
.pipe(gulp.dest("modules/newFolder/build"));
});
Here is the es6 file:
import d3 from 'd3';
import myFunc from 'modules/newFolder/es6module'
// ...
This will be compiled to sth like this:
define(['d3', 'modules/newFolder/es6module'], function (_d, _myFunc) {
'use strict';
// ...
});
as long as the module in define(['d3', 'modules/newFolder/es6module'], ... of the compiled file is fine in a original AMD file, it should work with under existing require.js setup, such as compress files etc.
In terms of #coderC's question about require.js loaders, I was using i18n!nls/lang in AMD modules, at first I thought it would be a really tricky thing to find an alternative of AMD plugin loaders in ES6 modules, and I switched to other localization tools such as i18next. But it turned out that it's okay to do this:
import lang from 'i18n!nls/lang';
// import other modules..
because it will be compiled by gulp task to sth like:
define(['d3', 'i18n!nls/lang'], function (_d, _lang) {
// ....
This way, we don't have to worry about the require.js loader.
In a nutshell, in ES6 modules, if you want to use existing AMD plugin/modules, you just need to ensure the compiled file is conformed with the existing setup. Additionally, you can also try the ES6 module bundler Rollup to bundle all the new ES6 files.
Hope this can be helpful for those who are trying to integrate ES6 syntax in project.
A few changes for the latest version of babel:
First, babel({"modules": "amd"}) doesn't work with the latest version of babel. Instead, use babel({"plugins": ["#babel/plugin-transform-modules-amd"]}). (You'll need to install that plugin as a separate module in npm, i.e. with npm install --save-dev #babel/plugin-transform-modules-amd.)
Second, the syntax for gulp.task no longer accepts arrays as its second argument. Instead, use gulp.parallel or gulp.series to create a compound task.
Your gulpfile will end up looking like this:
"use strict";
var gulp = require('gulp');
var babel = require('gulp-babel');
gulp.task("copy", function () {
return gulp.src(["./js/**/*.js", "./index.html"], { base: '.' })
.pipe(gulp.dest("build"));
});
gulp.task("compile-es6", function () {
return gulp.src("js/**/*.es6")
.pipe(babel({"plugins": ["#babel/plugin-transform-modules-amd"]}))
.pipe(gulp.dest("build/js"));
});
gulp.task("default", gulp.parallel("copy", "compile-es6"));
I want to use Browserify to bundle my files, but I then need to require one of the modules inside of my Browserify bundled bundle.js on the HTML page itself. This is currently not possible because there is no require function defined on the page.
It appears that the require function defined by browserify in bundle.js is inside of an IIFE, so I can't use that. Is it possible to throw this one out in place of a global require?
<script src="bundle.js"></script>
<script>
// Require the `app` module inside of `bundle.js`
var app = require('app');
app.start();
</script>
I need to do this because my app.start function requires some JSON is passed to it which can only be rendered by the server-side template.
N.B. I am using Browserify v2.
You can use -r to expose a global require() function for the files you specify:
x.js:
module.exports = function (n) { return n * 111 }
Console
$ browserify -r ./x.js > bundle.js
then in your html:
<script src="bundle.js"></script>
<script>
var x = require('./x.js');
console.log(x(3))
</script>
will print 333.
In your case, just do browserify -r app to expose require('app') to the external context.