Moving react into seperate component files without Node - javascript

I'm not using Node, how do move my react code (jsx) which is currently in a text/babel script tag into separate component files? I have tried moving them and then referencing them in the html file but as soon as it hits the first bit of HTML it throws a syntax error, I have tried both .jsx and .js extensions of the file and when I include it I give it the script type of text/babel.
<script src="components/nav.jsx" type="text/babel" ></script>
<script src="components/map.jsx" type="text/babel" ></script>
<script src="components/app.jsx" type="text/babel" ></script>

If you are transforming your JSX in the browser, you would have to attach each component to the window object.
As an example:
var Nav = React.createClass({ ... });
window.Nav = Nav;
Or more tersely:
window.Nav = React.createClass({ ... });

Jim Nielsen is right, however it is considered to be a bad practice to expose parts of you code to a global scope and to transpile JSX in the browser. Instead you should consider to use some building system like Webpack.
This way you would be able to use es2015 import syntax to import components from one file to another, bundle everything in one file and much more additional benefits like code minification, sourcemaps, livereload etc.
Setting up React for ES6 with Webpack and Babel
Using React with Webpack Tutorial
Related issue

Related

Adding react to existing web page (legacy) - imports not working

I have imported react dev to a webpage (legacy HTML+JQuery) as follows:
<script src="https://unpkg.com/react#17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom#17/umd/react-dom.development.js" crossorigin></script>
<script type="module" src="dist/Menu.js"></script>
and I'm trying to use the Menu component, which has the following code:
import menuData from "./menuData";
import MenuItem from "./MenuItem";
export const Menu = () => {
return (
<p>Some code..</p>
)
};
let domContainer = document.querySelector('#main_menu');
ReactDOM.render(<Menu />, domContainer);
In my legacy app, before importing I had to transpile the JSX to JS using:
npx babel --watch src --out-dir dist --presets react-app/prod,
And in my legacy app, in addition to the imports (above), I wrote the following element:
<div id="main_menu"></div>
but my legacy app shows an 404 Error for my imports:
404 https://mywebpage.com/dist/menuData
404 https://mywebpage.com/dist/MenuItem
Any idea what I'm missing? How I can start using React components (with imports of another components) in my legacy HTML+JQuery app?
Do the imported paths really exist on your site? Open a browser and go to
https://mywebpage.com/dist/menuData
If they don't resolve to plain .js source code - which it sounds like they don't - they won't work. You probably need to add the file extension, since it sounds like your server isn't doing it:
import menuData from "./menuData.js";
import MenuItem from "./MenuItem.js";
such that going to
https://mywebpage.com/dist/menuData.js
shows you the JS file.
But an even better option you might also consider would be to bundle the code together during a build process, so that only one .js file has to be served to the client. As an app grows larger and larger, if the client has to request 20 or 30 or more modules from your server, that can be a significant performance hit if you aren't using HTTP/2. Consider a module bundler like Webpack. You may be able to turn your HTML into
<script src="dist/bundle.js"></script>
by bundling all of your modules (and React, and any other libraries you happen to be using here) together into a single file.

import/export modules from packages like tippyjs in browsers using only JavaScript ES6

Is it possible to import, using only JavaScript ES6, modules from package like tippyjs (https://github.com/atomiks/tippyjs)?
I tried to locally install the package via npm and use the files like this:
import tippy from '../node_modules/tippy.js/dist/tippy.esm.js';
but the browser give me this error:
validation.ts:46 Uncaught ReferenceError: process is not defined
I have also tried, unsuccessfully, to "replicate" what the CDN is doing.
Thanks to what magic does the CDN work?
<script src="https://unpkg.com/#popperjs/core#2"></script>
<script src="https://unpkg.com/tippy.js#6"></script>
I know I am supposed to use CDNs, CDNs are great ecc., but I just want to have a single js module file in my HTML where all the import of my local files are:
<script type="module" src="js/modules.js"></script>
Can't rely only on CDNs.
What I am missing?
Please note that I'm not usign node.js, is just an html page and some JavaScript.
I don't think this can work with ES6 modules in the browser because of the way that tippy.js references popper. It uses the syntax import { createPopper, applyStyles } from '#popperjs/core'; which the browser can't understand. There's an issue about this on Github with regard to bootstrap, which has the same problem apparently.
I don't get the error you're getting by the way, I get the one in the issue. My HTML file is as below with tippy.js installed in the same folder:
<body>
<button id="myButton">My Button</button>
<script type="module">
import tippy from '../node_modules/tippy.js/dist/tippy.esm.js';
tippy('#myButton', {
content: 'Tooltip!',
});
</script>
</body>
Running this gives error:
Uncaught TypeError: Failed to resolve module specifier "#popperjs/core". Relative references must start with either "/", "./", or "../".
I don't think you can edit the import in tippy.js locally to fix this, either: popper's own imports then fail to work for me.
The workaround, as an answer to the issue says, is to use a module bundler like webpack if you want to create a .js file you can reference. This also begs the question of what the point is of an esm install if it can only be used from node.

Reactjs - Importing CSS/JS in component

I am trying to create a webpage using a HTML theme on Reactjs. I have studied and found there are 4 ways to import CSS at this link. All these ways outputs the same way i.e <style>MY_CSS</style> just before closing HEAD tag.
This is OK for single CSS but when we are using multiple CSS it may conflict with other one.
So my question is can we import CSS so that it will show in not as <style></style>. As <style> tags works as inline CSS and I don't want to use it inline.
2nd question: How can I import Js?
As I am using requirejs to load multiple js, for this I am trying to import require.config.js where my other js are called.
Please have a look what I am getting
Need to have like this below
Please help, thanks in advance!
This is just done via ordinary ES. For example:
import React, { Component } from 'react'
import './SomeFileWithStyle.css'
The second line imports a CSS file containing, well, CSS code. You are now able to use the classes specified in there. Follow this guide if you need further help: Styling and CSS - React.
Read more about the ES import statement here: import - JavaScript | MDN
The easiest way to learn React and the way you should structure a React project ( this includes everything, from css, to multiple js files, etc ) is to use create-react-app
Let me try to elaborate a bit.
React is a javascript library. You could, for example, get the library from a cdn and include it in your index.html file much in the same way you would get jquery for example. And, with the library included, you could do things like this:
const element = React.createElement(
'h1',
null,
'Hello, world!'
);
const container = document.getElementById('root');
ReactDOM.render(element, container);
Since you have the library from a cdn, you have access to it's methods, for example createElement and the library will look for a node in the dom with id called root and insert there a h1 node containing Hello, world!. You could then apply to the newly created node a style of your choice.
This example was taken from here
While it is certainly possible to use React this way, you shouldn't, in my opinion.
What you should do is follow the steps outlined in the create-react-app link and bootstrap a project using create-react-app. This will give you a pre configured project, that will allow you to use the library in a modern way.
The project that create-react-app offers you is set up to use a tool called webpack and a tool called babel. Webpack is a module bundler. Using a set of rules, it will take several files and bundle them together. How and why it works is beyond the scope of this question. Babel is a javascript compiler or syntax transformer. Also using a set of rules, it turns ES6 into regular javascript. Again, the how and the way are out of scope. What you should know is, because of webpack and babel, you will be able to write code like this.
import styles from 'style.module.css'
This is done with no effort on your part, because everything is already configured by create-react-app.
This is why I recommend you start with this. Just install it, bootstrap a project and take a quick look at how App.js is set up. You will see there css imports, component imports and will give you a good if shallow overview of how a modern React project works.
Import your .css file from the correct path. I struggled with using <link rel="stylesheet" href="css/style.css">
in index.html without any luck.
But instead:
index.html:
<link rel="stylesheet" href="/src/css/style.css"/>
style.css:
div.custom-div {
background-color: red;
}
Now, you can use
<div className="custom-div">
You need to use css-loader when creating bundle with wepback.
Install it:
npm install css-loader --save-dev
Read more here

Using Vue without bundlers?

I am creating some experimental web sites that are using JavaScript without bundling. For dependency management I have used RequireJS until now, but I have started to use SystemJS recently since it has some very nice support for HTTP2. I have done some experiments so far on my custom set web server and results are great for the web sites I am creating. For example, first page render happens around 400ms, full page load at 800ms etc.
I am doing this because I want to take full advantage of HTTP2 and I want to lazy load only scripts that I am using at a certain moment. Code like that is easier to maintain, it’s cached better etc. At the moment there is a total craze about bundlers like Webpack, but that is not something I want to use.
Here is the question: is there a way to compile single Vue file / components by using Gulp and then load them with SystemJS as AMD or CommonJS modules?
edit:
This is what I want to achieve with SystemJS and Vue:
entry point JS file:
// SystemJS config
SystemJS.config({
/* ... */
baseURL: './',
map: {
// App
'app': 'scripts/app.min.js',
// Utils
'axios': 'scripts/vendor/axios/axios.min.js',
'modernizr': 'scripts/vendor/modernizr/modernizr.min.js',
// Framework
'vue': 'scripts/vendor/vue/vue.min.js',
// Components
'vueHelloWorld': 'scripts/components/hello/vueHelloWorld.js', // <- Compiled VUE component
'vueMenu': 'scripts/components/menu/vueMenu.js'
},
depcache: {
'vueHelloWorld': ['vue'],
'vueMenu': ['vue', 'vueHelloWorld']
}
/* ... */
)};
// Initially Load default scripts
require(['modernizr', 'axios', 'app']);
Vue components vueHelloWorld.js and vueMenu.js are end result, compiled into pure JS from single file templates vueHelloWorld.vue and vueMenu.vue.
After that initial file, app.min.js is loaded and it will have declarations to load rendered vue components.
This is what I don't know how to do - how to render separate files for each Vue component that I want to load in this manner?
If I understand the question correctly, all you are looking for is something that takes a single *.vue file and returns a single compiled *.js file. You could either try and write your own thing using https://github.com/vuejs/vue-component-compiler, or what I ended up doing is misusing rollup as my vue compiler, configuring it, so that it ignores all dependencies and therefore takes one vue component in and only compiles that one component. Here you can see the config that achieves that: https://github.com/ecosia/bazel_rules_nodejs_contrib/blob/master/internal/vue_component/rollup.config.js
It seems that Async components and webpacks code splitting are what you are looking for.
Here you find an article about using them:
https://vuejsdevelopers.com/2017/07/03/vue-js-code-splitting-webpack/
No, because single Vue file (*.vue) can only be recognized by vue-loader through webpack, SystemJS or AMD or CommonJS are totally unrelated to it, these three are modularity standards or ways to make your javascipts files organized.
Also u can write in this way.
a.component.js
var ComponentA = {
template: '#view-a',
}
b.component.js
var ComponentB = {
template: '#view-b',
}
then in your html file
<script type="text/x-template" id="view-a">
<div> .... </div>
</script>
<script type="text/x-template" id="view-b">
<div> .... </div>
</script>

Require reactjs modules without Browserify, Webpack or Babel

I'm trying to setup TypeScript HTML app in visual studio. I want to use reactjs v0.14.7
I would like to avoid using tools like Browserify.
However, how to use the react-dom module then?
Let's forget about typescript for a while. I need to get pure ES5 up and running first.
currently, I have this:
<script src="Scripts/react/react.js"></script>
<script src="Scripts/react/react-dom.js"></script>
<script>
var Button = React.createClass({
render: function () {
return (React.createElement("div", { className: "btn btn-default" }, 'hello world'));
}
});
ReactDOM.render(React.createElement('Button'), document.getElementById('container'));
</script>
however, browser complains, ReactDOM object does not exists.
I have tried:
<script src="Scripts/require.js"></script>
<script src="Scripts/react/react.js"></script>
<script src="Scripts/react/react-dom.js"></script>
<script>
var React = require('react');
var ReactDOM = require('react-dom');
....
</script>
however, it does not work with require.js: Module name "react" has not been loaded yet for context: _. Use require([])
Can someone bring a little more light into this, please? How to use react without any server side tools like bundling, transpiling etc.
Answers like "use npm" won't be accepted as answer.
RequireJS and require are very different things - more on that later.
If you want to use React without a tool like Browserify or Webpack, then you don't necessarily need a module loader. The hosted versions of React and ReactDOM will expose global variables that you can use out of the box.
<script src="https://fb.me/react-0.14.7.js"></script>
<script src="https://fb.me/react-dom-0.14.7.js"></script>
<script>
console.log(React, ReactDOM);
</script>
Just download these files if you want to work with them locally.
SystemJS
All of that out the way, it sounds like SystemJS and JSPM might be exactly what you're looking for.
First use jspm to install your packages.
jspm install systemjs react react-dom
Then link and configure SystemJS.
<script src='jspm_packages/system.js'></script>
<script>
System.import('app.js');
</script>
Now inside app.js you can write CommonJS style code.
var React = require('react');
var ReactDOM = require('react-dom');
SystemJS will handle the loading of the rest of your scripts. If you want to make a production build, then it's as simple as running jspm bundle app.
CommonJS
The calls to require that you're seeing in the React tutorials and other examples are for a module format called CommonJS.
You use require('react') to get a reference to the value exported by the React module (installed into node_modules with npm). This means you need a pre-browser build step like Browserify or Webpack, that can staple all of the modules you need together and output one big script file.
RequireJS
Confusingly, CommonJS and RequireJS use a function with the same name to specify dependencies. You're trying to use the RequireJS require function as though you were working with CommonJS modules.
If you want to import React with RequireJS instead, then you need to something like this:
<script src="js/require.js"></script>
<script>
require.config({
'baseUrl' : 'Scripts/',
});
require(["react-0.14.7", "react-dom-0.14.7"],
function(React, ReactDOM) {
console.log(React, ReactDOM);
});
</script>
When your code executes, RequireJS will go off and add script tags for the modules you've specified. Then once these scripts have loaded, it will pass the values that they export into the callback function for you to use.
Take a look at this project
https://github.com/ORESoftware/hr4r2
it is doing what you want to do - it is using RequireJS + React + TypeScript. And it is doing serverside rendering and is a SPA.
This project is not using Webpack or Babel.
Here is an example by Dan Abramov himself, the creator of Redux in which he makes a react app without using webpack, babel or browserify.
http://codepen.io/gaearon/pen/ZpvBNJ?editors=0010
In your HTML file inside your body tag write
<div id="root">
<!-- This div's content will be managed by React. -->
</div>
And In your script tag type this
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('root')
);
PS Make Sure You Include These 2 Libraries At Top
https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.js
https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react-dom.js
Hope it helps.

Categories

Resources