Babel: use subset of stage-x preset plugins? - babeljs

How can I use two specific Babel plugins that are in a stage-x "preset", without having to use the entire preset?
Specifically, I want to use transform-class-properties and transform-decorators in my ES6 classes, both currently proposed for ES7 and part of the stage-1 preset.

presets are just a collection of smaller plugins, so you can use that option to pull in the transforms you need:
.babelrc (Or config)
{
"presets": ["es2015"],
"plugins": ["transform-class-properties", "transform-decorators"]
}
Will give you all ES2015 + Class Properties + Decorators

#RGraham's answer was helpful--also wanted to share more details...
I'm using gulp, so first I had to upgrade from gulp-babel 5.x to 6.x:
npm install --save-dev babel/gulp-babel
Then I needed to install ES2015 preset and the two plugins I want to use (+ the react preset since I'm using ReactJS):
npm install --save-dev babel-preset-es2015
npm install --save-dev babel-preset-react
npm install --save-dev babel-plugin-transform-class-properties
npm install --save-dev babel-plugin-transform-decorators
Last, I passed the following config to Babel (you could also specify this in your .babelrc file):
{
presets: ['es2015', 'react'],
plugins: [
["transform-class-properties"],
["transform-decorators"]
]
}
Your JavaScript linter will complain about the ES7 syntax. This blog post described the solution: modify lintjs to use Babel as the JavaScript parser. Set "parser": "babel-eslint" in your .eslintrc file then
npm install --save-dev babel-eslint
Lastly for any other ReactJS folks, make sure you modify your component's constructor to include the props and context arguments or else you may get a runtime error like TypeError: Cannot read property 'xxx' of undefined. Here's an example:
/**
* ES6 constructor method (takes the place of the old React componentWillMount() method).
*
* #param {Object} props See https://facebook.github.io/react/docs/reusable-components.html
* #param {Object} context See https://facebook.github.io/react/docs/context.html
*/
constructor(props, context) {
super(props, context);
log.debug(`Creating ${this.constructor.name} instance`, props, context);
}

Related

How to include karma reporter without publishing it as npm package

I want to use a self-written karma reporter which, however, is not intended to be published as a separate npm module. After reading both documentation and source code I'm still having hard times to figure out how exactly this should be done.
From code I see now this is sort of hardcoded in that sense that there's a one-to-one correspondence between the name of the reporter (say, "somereporter") and the name of npm package karma tries to refer to - in this case it's gonna be karma-somereporter-reporter.
So, I finally figured it out. In order to add a local reported you need to include it as plugin, for instance:
module.exports = function (config) {
config.set({
plugins: [
require('../../MyReporter.js')
],
reporters: ['myreporter']
})
}

React Serverside rendering Unexpected token, JSX and Babel

I'm having trouble finding the correct way to use babel to allow me to use jsx in serverside.
Node-jsx was deprecated for babel. It seems like babel-core/register is whats supposed to be used but I still get unexpected token issues.
I created a repo with the problem im having.
https://github.com/pk1m/Stackoverflow-helpme
When I run node app or npm run watch-js I keep getting unexpected token referring to the JSX code '<'.
How do I get babel to transpile JSX, or am I completely off, thanks.
You need to use babel-register (npm i babel-register --save). And run on your server:
require('babel-register')({
stage: 0
});
You can omit stage 0 if you aren't using experimental babel features. Also you might prefer to put those options in .babelrc instead.
Note that it will only work for files required AFTER calling that (so it would not have an effect on the file you include it in).
You could also have the presets and other options in a .babelrc file.
For babel 6x:
npm i babel-register babel-preset-es2015 babel-preset-react --save
require('babel-register')({
presets: ['es2015', 'react']
});
Note: there are also stage 0-2 presets.
For watching as you've written in your package.json you could try a CLI command like the one facebook are suggesting in the note here (or use webpack):
babel --presets react es2015 --watch app/ --out-dir build/

How to use blueimp-file-upload with webpack?

I'm using blueimp-file-upload in my website, and I'm using webpack to organize my js code.
I installed blueimp-file-upload and jquery.ui.widget from NPM
npm install --save blueimp-file-upload
npm install --save jquery.ui.widget
and I require blueimp-file-upload in my entry file
require('blueimp-file-upload')
but when I run webpack, I get thie error:
ERROR in ./~/blueimp-file-upload/js/jquery.fileupload.js
Module not found: Error: Cannot resolve module 'jquery.ui.widget' in E:\app-parent\cooka-common-web\src\main\resources\static\node_modules\blueimp-file-upload\js
# ./~/blueimp-file-upload/js/jquery.fileupload.js 19:8-22:19
If you're working with images:
Webpack was complaining about some modules that weren't in the blueimp-file-upload package. Here is the way I got this working:
Install missing dependencies:
npm i -S blueimp-load-image
npm i -S blueimp-canvas-to-blob
Configure Webpack:
config.resolve = {
extensions: ['', '.js'],
alias: {
'load-image': 'blueimp-load-image/js/load-image.js',
'load-image-meta': 'blueimp-load-image/js/load-image-meta.js',
'load-image-exif': 'blueimp-load-image/js/load-image-exif.js',
'canvas-to-blob': 'blueimp-canvas-to-blob/js/canvas-to-blob.js',
'jquery-ui/widget': 'blueimp-file-upload/js/vendor/jquery.ui.widget.js'
}
};
Include scripts in your app:
import "blueimp-file-upload/js/vendor/jquery.ui.widget.js";
import "blueimp-file-upload/js/jquery.iframe-transport.js";
import "blueimp-file-upload/js/jquery.fileupload.js";
import "blueimp-file-upload/js/jquery.fileupload-image.js";
Disable both AMD and CommonJS and use the Browser Global jQuery.
/* The jQuery UI widget factory, can be omitted if jQuery UI is already included */
require('imports?define=>false&exports=>false!blueimp-file-upload/js/vendor/jquery.ui.widget.js');
/* The Iframe Transport is required for browsers without support for XHR file uploads */
require('imports?define=>false&exports=>false!blueimp-file-upload/js/jquery.iframe-transport.js');
/* The basic File Upload plugin */
require('imports?define=>false&exports=>false!blueimp-file-upload/js/jquery.fileupload.js');
/* The File Upload processing plugin */
require('imports?define=>false&exports=>false!blueimp-file-upload/js/jquery.fileupload-process.js');
/* The File Upload validation plugin */
require('imports?define=>false&exports=>false!blueimp-file-upload/js/jquery.fileupload-validate.js');
/* The File Upload Angular JS module */
require('imports?define=>false&exports=>false!blueimp-file-upload/js/jquery.fileupload-angular.js');
This is the configuration I'm using to integrate webpack, blueimp-fileupload with angular. Alternatively you can configure in your webpack.config.js as a regex to avoid repeating loaders.
resolve: {
extensions: ['', '.js'],
alias: {
'jquery-ui/widget': 'blueimp-file-upload/js/vendor/jquery.ui.widget.js'
}
}
I had almost identical problem, except that Error announced not 'jquery.ui.widget' but 'jquery/ui/widget'.
For me #Gowrav answer was wrong way.
After days of straying I've solved it in the simple way. Just did:
npm install jquery-ui
The fact is that jquery.fileupload.js searching for its vendor:
But in context where jquery.fileupload.js is trying to import dependency, of course, it can't be found (resolved). So I add it to project instead.
P.S. It's just my opinion about how does all work. But this way has helped me.
jquery.fileupload.js checks for AMD require first which results in this error. You can teach webpack not to use AMD style for this file. (Make sure to npm install imports-loader for this method to work.):
require('imports?define=>false!blueimp-file-upload')
It should correctly register the module as CommonJS and will require the jquery.ui.widget from the right location.
Read more here: http://webpack.github.io/docs/shimming-modules.html#disable-some-module-styles
You can add an alias to jquery.ui.widget's main file - it unfortunately doesn't specify one in its package.json, so webpack can't find it otherwise.
resolve: {
alias: {
"jquery.ui.widget": "node_modules/jquery.ui.widget/jquery.ui.widget.js"
}
},
first install two plugins
npm i blueimp-file-upload --save
npm i jquery-ui --save
then require in web pack
require('blueimp-file-upload/js/jquery.fileupload')
actually you can solve this by changing your webpack config, just add the path to resolve (for example I am using bower)
resolve: {
extensions: [ '', '.js', '.jsx' ],
modulesDirectories: [
'node_modules',
'bower_components',
'bower_components/blueimp-file-upload/js/vendor'
]
}
In webpack 3.x, the syntax will look like this:
{
test: require.resolve("blueimp-file-upload"),
use: "imports-loader?define=>false"
}

Create shim for ember-cli

I am trying to create shim for getstream library for ember-cli as #jmurphyau answered here.
I bower install getstream, then create file
vendor/shims/getstream.js
(function() {
/* globals define, getstream */
function getstreamModule() {
'use strict';
return getstream; // <-- got error here
}
define('getstream', [], getstreamModule);
})();
and add lines to Brocfile.js
app.import('bower_components/getstream/dist/js_min/getstream.js');
app.import('vendor/shims/getstream.js', {
exports: {
'getstream': [ 'default' ]
}
});
and try to import Stream from 'getstream'; in route.
Got Uncaught ReferenceError: getstream is not defined in getstream.js
What's going wrong and how it could be fixed? Thanks for answers.
Have you tried using ember-browsify?
That library doesn't look like it exposes a global variable called getstream which is why your getting that error.
It does however look like it supports CommonJS module syntax so ember-browserify should work.
Install ember-browserify
ember install ember-browserify
Install the CommonJS library as an NPM package
npm install --save-dev getstream
Use the NPM package with regular import syntax
import getstream from 'npm:getstream';

How can I setup webpack to minify and combine scss and javascript like CodeKit?

I'm having trouble using webpack instead of Codekit v1.9.3. I started working to move from CodeKit to Grunt and Gulp, and then learned about webpack which sounds very cool. I just can't seem to get it working correctly.
"Like Codekit" means I can:
Write javascript with the coffeescript syntax
Have all script source files and libraries minified / uglified and combined into one file
Selectively include components of the bootstrap-sass (scss) framework as needed
Maintain a small file with bootstrap customizations via sass variables, like $brand-primary
Use webpack --watch to compile both scripts and styles automatically when they are changed
End up with one css file and one script file that can be included with a stylesheet and script tag.
Codekit Project Setup
Bower resources:
I'm currently storing these globally, outside of the project:
~/bower_components/twbs-bootstrap-sass/vendor/assets/stylesheets
Because CodeKit supports compass, I've got this in my config.rb file:
add_import_path "~/bower_components/twbs-bootstrap-sass/vendor/assets/stylesheets"
Project Structure
js/fancybox.js
js/main.js <-- currently the compiled js 'output' file
js/main.coffee
css/styles.css <-- currently the compiled css 'output' file
scss/styles.scss
scss/modules/_bootstrap-customizations.scss
scss/modules/_typography.scss
scss/partials/_header.scss
scss/partials/_footer.scss
Contents of styles.scss
#import "modules/bootstrap-customizations"; # local customizations
#import "bootstrap/variables";
#import "bootstrap/mixins";
... # load bootstrap files as required
#import "bootstrap/wells";
System Setup:
system: OS X 10.9
node - v0.10.32
npm - v2.1.7
zsh - zsh 5.0.7 (x86_64-apple-darwin13.4.0)
node was installed with homebrew's brew install node and seems to be working fine otherwise.
What I've Tried
I've read over these pages:
http://webpack.github.io/docs/configuration.html
https://github.com/petehunt/webpack-howto
http://webpack.github.io/docs/tutorials/getting-started/
https://www.npmjs.org/package/bootstrap-sass-webpack
I've attempted to create a webpack.config.js file several times, my latest attempt was several versions of this:
module.exports = {
entry: [
"./node_modules/bootstrap-sass-webpack!./bootstrap-sass.config.js",
"./js/main.coffee"
],
output: {
path: __dirname,
filename: "main.js"
},
module: {
loaders: [
{ test: /\.css$/, loader: "style!css" }
]
}
};
Webpack Error
When I run webpack I get this:
ERROR in ./~/bootstrap-sass-webpack/~/css-loader!/Users/cwd/~/sass-loader!./~/bootstrap-sass-webpack/bootstrap-sass-styles.loader.js!./bootstrap-sass.config.js
stdin:1: file to import not found or unreadable: "~bootstrap-sass/assets/stylesheets/bootstrap/variables
NPM Error
I get an error when attempting to npm install bootstrap-sass, and not had any luck when searching for a solution. I'm not even sure I need this module.
npm ERR! Darwin 13.4.0
npm ERR! argv "node" "/usr/local/bin/npm" "install" "bootstrap-sass"
npm ERR! node v0.10.32
npm ERR! npm v2.1.7
npm ERR! code EPEERINVALID
npm ERR! peerinvalid The package bootstrap-sass does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer bootstrap-sass-webpack#0.0.3 wants bootstrap-sass#~3.2.0
npm ERR! Please include the following file with any support request:
npm ERR! /Users/cwd/webpack-test/npm-debug.log
Sources of Confusion
The most confusing parts of webpack for me are:
Where should things like require("bootstrap-sass-webpack") be added - is it in the webpack.config.js file, or in the js/main.js file?
Should modules like this available to webpack as soon as they are installed with npm install ?
I thought that I should do npm install webpack -g so that webpack was installed globally, and use npm install without the -g for the other modules. However, I don't see any node_modules folder being created in my project. Shouldn't there be one?
How are the search paths determined / specified for things like require("bootstrap-sass-webpack") ?
What node modules should I install to be able to do this? And what should my webpack.config.js look like?
Introduction
Webpack is mainly a JavaScript-bundler. Its "native" language is JavaScript and every other source requires a loader which transforms it to JavaScript. If you require() an html-file for example...
var template = require("./some-template.html");
...you'll need the html-loader. It turns...
<div>
<img src="./assets/img.png">
</div>
...into...
module.exports = "<div>\n <img src=\"" + require("./assets/img.png") + "\">\n</div>";
If a loader doesn't return JavaScript, it needs to be "piped" to another loader.
How to load SASS-files
Configure loaders
In order to use SASS you'll need at least the sass-loader and the css-loader. The css-loader returns a JavaScript string. If you want to import the returned JavaScript string as StyleSheet, you'll also need the style-loader.
Run npm i sass-loader css-loader style-loader --save
Now you need to apply these loaders on all files that match /\.scss$/:
// webpack.config.js
...
module: {
loaders: [
// the loaders will be applied from right to left
{ test: /\.scss$/, loader: "style!css!sass" }
]
}
...
You can also pass options to node-sass as query parameters:
{
test: /\.scss$/, loader: "style!css!sass?includePaths[]=" +
path.resolve(__dirname, "./bower_components/bootstrap-sass/assets/stylesheets/"
}
Since bootstrap references icons via the url() statement, the css-loader will try to include these assets into the bundle and will throw an exception otherwise. That's why you'll also need the file-loader:
// webpack.config.js
...
module: {
loaders: [
{ test: /\.scss$/, loader: "style!css!sass" },
{ test: /\.jpe?g$|\.gif$|\.png$|\.svg$|\.woff$|\.ttf$/, loader: "file" },
]
}
...
Configure entry
To include bootstrap into your bundle there are several ways. One is via the multi-entry option as you've already tried. I recommend to use a single entry where you require() your main sass-file:
// main.js
require("./main.scss");
Given that your includePaths are configured then you can do:
// main.scss
// Set the font path so that url() points to the actual file
$icon-font-path: "../../../fonts/bootstrap";
#import "bootstrap";
Please note that import statements inside scss-files are not touched by webpack because libsass has no api (yet) to provide custom resolvers.
To prevent code duplication it's also important to have a single main sass-file, because webpack compiles every sass-file individually.
With the coffee-loader installed via npm your final webpack.config.js should look like:
module.exports = {
entry: "./js/main.coffee",
output: {
path: __dirname,
filename: "main.js"
},
module: {
loaders: [
{ test: /\.scss$/, loader: "style!css!sass" },
{ test: /\.jpe?g$|\.gif$|\.png$|\.svg$|\.woff$|\.ttf$/, loader: "file" },
{ test: /\.coffee$/, loader: "coffee" }
]
}
};
Webpack globally?
It's best not to install webpack globally, because it's a dependency of your project and thus should be controlled via npm. You can use the scripts-section of your package.json:
{
...
"scripts": {
"start": "webpack --config path/to/webpack.config.js & node server.js"
}
}
Then you just need to run npm start