I am using grunt to transpiling react jsx files and it's perfectly works as expected by using grunt-babel along with presets: ["env", "react"],plugins: ["transform-es2015-modules-amd"]
The problem I have is,grunt-babel transpiling JSX files which are placed in a same directory but I need to transpile JSX files which are one level up to root folder directory.Below is the detail explanation:
Folder Structure :
ReactApp
- App // grunt-babel and relevant plug-ins, presets installed here
- config
- node_modules
- JSX // it's transpiling and working
- test.jsx
- JSX_generated
- test.js
- gruntfile
- package
- JSX // jsx file source and it's not transpiling
- test.jsx
- JSX_generated // transpiled jsx file output expected
- test.js
- App.js
- index.html
gruntfile :
module.exports = function (grunt) {
'use strict';
grunt.initConfig({
babel: {
options: {
sourceMap: false,
presets: ["env", "react"],
plugins: ["transform-es2015-modules-amd"]
},
dist: {
files: [{
expand: true,
cwd: './JSX',
src: ['*.jsx'],
dest: './JSX_generated',
ext: '.js'
}]
}
}
});
grunt.loadNpmTasks('grunt-babel');
grunt.registerTask('default', ['babel']);};
Above grunt config is woring fine for the jsx folder placed under App folder, the thing is I need to transpile the JSX folder which is placed out of App folder.
Changed grunt config cwd as cwd: './../JSX' , dest as dest: './../JSX_generated',
Getting the following error :
Running "babel:jsx" (babel) task
Warning: Unknown plugin "transform-es2015-modules-amd" specified in "base" at 0, attempted to resolve relative to "../JSX"
sample jsx file :
import React from 'react';
import AppData from './AppData';
import Loader from './Loader';
class Test extends React.Component {
render() {
return <p>hello </p>
}
}
ReactDOM.render(<Test />, document.getElementById('container'));
Is there a way to transpile files one level up from the grunt or node have been installed ?
For anyone having an issue like this, the solution is use
absolute paths
../Users/app/node_modules/babel-preset-es2015
or use require like below :
var babelenv = require('babel-preset-env');
var babelreact = require('babel-preset-react');
var babelamd = require('babel-plugin-transform-es2015-modules-amd');
and presets: [ babelenv, babelreact],plugins : [ babelamd ]
Related
I'm new to React and I'm still trying to understand how things are put together. In webpack, I understand that we have to run the webpack command initially and it will generate the index.js file where we output it in the config. For my questions:
What role does this file play in runtime?
Everytime i do an npm start, does it automatically update my index.js file?
Here is my webpack.config:
var config = {
entry: './main.js',
output: {
path: __dirname,
filename: 'index.js',
},
devServer: {
inline: true,
port: 8080
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: ['es2015', 'react']
}
}
]
}
}
module.exports = config;
With or without initially running webpack command my code still runs, reason for me being confused as to what it really does, because even without having the index.js in my directory I'm still able to run my code
Why we are using webpack:
When we run webpack command it will create a single index.js file in given the location.Our browser understands only vanilla html, css and javascript.But with react you are probably going to use jsx or es6. So we need to transform these to what browser understands.
According to your webpack.config , webpack is going to convert all jsx file into .js file (using bable loader)and bundle it to a single file as index.js.
Role plays by index.js:
You will be having an index.html file in your app directory.webpack automatically load index.js file to body of index.html file.This if final index.js file browser is going to use.
If you are using following configuration in package.json
{
"scripts": {
"dev": "webpack -d --watch",
"build" : "webpack -p"
},
}
then webpack keeps watching any changes in .jsx file and update index.js
As you are saying you code is running without webpack.It means you are using simple .js file.But to use es6 or .jsx you need webpack.
Hope it helps!. For more you can read https://tylermcginnis.com/react-js-tutorial-1-5-utilizing-webpack-and-babel-to-build-a-react-js-app/
I'm starting to learn ReactJs, and I was trying to build an environment from scratch using this "builder".
Everything works pretty well, but I'd like to work with .jsx files instead of .js (the text editor screws up otherwise, and ir feels better using a different extension for not-compiled scripts)
However, I didn't manage to compile such .jsx files, it only works with .js files.
This is the configuration files for .babelrc:
{
"presets":["es2015","react"]
}
And my webpack.config.js:
var path = require('path');
var config = {
context: path.join(__dirname,'src'),
entry:[
'./main.js'
],
output:{
path :path.join(__dirname,'www'),
filename:'bundle.js'
},
module:{
loaders:[
{
test: /\.js$/,
exclude:/node_modules/,
loaders:['babel']
}
],
},
resolveLoader:{
root: [
path.join(__dirname,'node_modules')
]
},
resolve:{
root:[
path.join(__dirname,'node_modules')
]
}
};
module.exports = config;
I tried simply changing the extensions in the webpack config file from js to jsx, but to no avail.
Any ideas?
Just replace this line:
test: /\.js$/,
with:
test: /\.jsx$/,
It will run babel loader on the .jsx files, instead of .js files.
If you want to transpile both .js and .jsx, you can set it to /\.jsx?$/, where ? in regex indicates to match 0 or 1 occurrences of the preceding character: test positive for both .js and .jsx.
.test property indicates a condition that must be met to run the loader specified in the loader key. You can read more about module.loader options here.
Also, when importing modules, you should add the .jsx extension, like this:
import Counter from './Counter.jsx';
Or set webpack's resolve.extensions config to add .jsx extension (by default, it looks only for .js files). Like this:
resolve: {
/* ... */
extensions: ['', '.js', '.jsx']
}
This way, you can import your files without the extension:
import Counter from './Counter';
I am trying to setup a react based component library using browserify. This is importing other react based component library as a node module. Following is the browserify configuration in grunt-browserify.
{
options: {
"transform": [
[
"babelify",
{
"presets": [
"es2015",
"react",
"stage-0"
]
}
]
],
browserifyOptions: {
debug: true,
extensions: ['.js', '.jsx'],
entries: ['./src/js/index.js']
}
},
dist: {
src: ['src/index.js'],
dest: 'dist/index.js'
}
}
I am importing a node module which contains react component.
import orb from 'orb';
import React from 'react';
class ReactComponent extends React.Component {
componentDidMount() {
this.ptable = new orb.pgridwidget(this.props.config);
this.ptable.render(ReactDom.findDOMNode(this));
}
render() {
return (<div></div>);
}
}
export ReactComponent;
I am getting following error.
SyntaxError: Unexpected token (102:12) while parsing //node_modules/orb/src/js/react/orb.react.PivotChart.jsx while parsing file: //node_modules/orb/src/js/react/orb.react.PivotChart.jsx
Token position being mentioned is basically jsx. Looks like babelify is not using preset react for node_modules. How to make browserify use babel presets react for this file?
Update
While working on webpack I have faced similar issue which I was able to resolve later. But looks like browserify don't accept additional files like webpack does. Tried options like noParse, external but those are not working.
Able to resolve the issue by adding node module main file to entries object. This is not clearly mentioned in definition for entries in config object.
browserifyOptions: {
debug: true,
extensions: ['.js', '.jsx'],
entries: ['node_modules/orb/src/orb.js', './src/js/index.js']
}
Added a new entry in browserifyOptions
I am about to move angular 1 + typescript project build setup from gulp to webpack, the only part I am stuck with is, how to bundle node_modules js file in proper sequence.
I was till now using bower for client side dependencies, and gulp has wiredep plugin which will look into bower dependencies section + main section to build the dependency order and get it to bundle it properly.
Now I understand that webpack philosophy is different, we should depend upload whatever is imported rather than any dependencies section as such.
so to get it to work I will need to do: move all dependencies from bower.json to package.json
currently as I am using typings, tsc considers the typings and gives me the output, I really don't need to write imports for bower packages as such.
So if i understand correctly, to get it work with webpack,
a) I should get away with typings and then directly import the js
files inside all my ts files??
As I understand, all the js modules from npm do work with modules, so does webpack really needs typings files?
OR
b) I should write a separate vendor.ts, where I should maintain the
sequence of imports (for js and css) myself,
but then that would be little painful to do (given I am used to wiredep handling it for me).
But then this will allow me bundle the vendor files separately using chunks-plugin
OR
c) is there any other standard way to handle this.
This is kinda pain point to move angular 1 from gulp to webpack.
When you import a module from a TypeScript file that's going to be loaded by webpack, it'll get it's content from node_modules and bundle it into the output file.
index.ts
import * as angular from "angular";
const myApp = angular.module("myApp", []);
myApp.controller("MyController", function PhoneListController($scope) {
$scope.phones = [
{
name: "Nexus S",
snippet: "Fast just got faster with Nexus S."
}, {
name: "Motorola XOOMâ„¢ with Wi-Fi",
snippet: "The Next, Next Generation tablet."
}, {
name: "MOTOROLA XOOMâ„¢",
snippet: "The Next, Next Generation tablet."
}
];
});
index.html
<!DOCTYPE html>
<html ng-app="myApp">
<head>
...
<script src="bundle.js"></script>
</head>
<body ng-controller="MyController">
<ul>
<li ng-repeat="phone in phones">
<span>{{phone.name}}</span>
<p>{{phone.snippet}}</p>
</li>
</ul>
</body>
</html>
webpack.config.js
module.exports = {
entry: "./index.ts",
output: {
filename: "./bundle.js"
},
devtool: "source-map",
resolve: {
extensions: ["", ".webpack.js", ".web.js", ".ts", ".tsx", ".js"]
},
module: {
loaders: [
{ test: /\.tsx?$/, loader: "ts-loader" }
],
preLoaders: [
{ test: /\.js$/, loader: "source-map-loader" }
]
}
};
Add angular, #types/angular, ts-loader, source-map-loader, typescript to your packages.json and run webpack.
It'll bundle everything inside a single file named bundle.js which will be used by your index.html.
Question
Why cant my Grunt Typescript compiler find the angular core?
I guess it has something to do with the paths so the compiler cant find the libs in the node_modules directory.
Error
typescript/add.component.ts(1,25): error TS2307: Cannot find module 'angular2/core'.
Setup
Gruntfile.js Task
typescript: {
all: {
src: ['typescript/**/*.ts'],
dest: 'javascript/frontend',
options: {
target: "es5",
module: "system",
moduleResolution: "node",
emitDecoratorMetadata: true,
experimentalDecorators: true,
removeComments: false,
noImplicitAny: false
}
}
typescript/add.component.ts
import {Component} from 'angular2/core';
#Component({
selector: 'mytest',
template: '<h1>test</h1>'
})
export class AppComponent { }
node_modules
Includes angular2
Includes typescript
Filepaths
app -- node_modules
-- typescript
-- app.component.ts
-- Gruntfile.js
-- package.json
Used libs/frameworks/tutorials
Grunt Typescript Github
Angular2 5min Quickstart
Just now I had the same exact problem. Running grunt in verbose mode showed the content of the ts config file it generated from the grunt config. Looking more closely, this revealed that the moduleResolution option isn't used at all. But, on the other hand, it wasn't described either on the official grunt-typescript page.
Anyway, long story short: I've used the grunt-ts package instead and everything worked out well! I've posted my config below for your convenience :-)
module.exports = function(grunt) {
grunt.initConfig({
ts: {
base: {
src: ['src/**/*.ts'],
dest: 'dist',
options: {
module: 'system',
moduleResolution: 'node',
target: 'es5',
experimentalDecorators: true,
emitDecoratorMetadata: true,
noImplicitAny: false
}
}
}
});
grunt.loadNpmTasks('grunt-ts');
grunt.registerTask('default', ['ts']);
};