I am having trouble getting React components to work in my Twig templates in Symfony2, using RequireJS to initiate them. I was trying to get this one to work: https://github.com/rackt/react-autocomplete
First I installed it, locally, in parallel to where I have my css files for my templates:
npm install react-autocomplete
Then, some selected parts from my twig template:
<html>
<head>
<script src="https://fb.me/react-0.13.1.js"></script>
<script src="https://fb.me/JSXTransformer-0.13.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.17/require.min.js"> </script>
</head>
<body>
<div id="react_demo">
<script type="text/jsx">
require(["{{asset('/bundles/demobundle/js/node_modules/react-autocomplete')}}"], function (ReactAutocomplete) {
alert('react-autocomplete loaded');
});
</script>
</div>
</body>
</html>
And now, to the problem: it doesn't seem to find my React component - or doesn't understand that it is a React component I'm trying to load... for some background info I haven't done anything except for including the React and Require JS files, and install the component. Perhaps I've missed something?
Uncaught Error: Load timeout for modules: /bundles/demobundle/js/node_modules/react-autocomplete
That one looks like a CommonJS module and while those can be loaded with RequireJS it needs some additional configuration.
While the packages can have the CommonJS directory layout, the modules themselves should be in a module format that RequireJS can understand. Exception to the rule: if you are using the r.js Node adapter, the modules can be in the traditional CommonJS module format. You can use the CommonJS converter tool if you need to convert traditional CommonJS modules into the async module format that RequireJS uses.
Also see http://requirejs.org/docs/commonjs.html and https://stackoverflow.com/a/16522990/1630906
Related
I have a big old website that I am adding react components to. It uses node/express and handlebar templates mostly. Basically I do it like this:
The site imports react libs in the old way (in an html file):
<script src="https://unpkg.com/react#16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom#16/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone#6/babel.min.js"></script>
And then I use it like this:
HTML:
<div id="react-container"></div>
<script src="react-component.jsx" type="text/babel"></script>
react-component.jsx:
const Component = ()=>{ ... }
const container = document.getElementById("react-container");
ReactDOM.render(React.createElement(Component), container);
The issue is if I want to import libraries, they have to be available from CDN via script tags. I have found a couple now that aren't and also it would be nice to be able to see what I'm importing at the top of a file instead of just having a bunch of libraries floating around on the window object.
Anway, I can't use create-react-app but I'm wondering how I can go about inserting a small build step into my system to make it possible to npm/yarn install libs and then import them into my code.
Thanks.
I am not familiar with the technologies you're using but I thought your question was interesting and I looked a bit into it.
Here is what I would try to do:
Since you're using node you could use Webpack to bundle each of your react components in its own separate file (https://webpack.js.org/concepts/output/#multiple-entry-points) and tell Webpack to put the generated files in a folder that can be served by express. (https://expressjs.com/en/starter/static-files.html). Webpack will take care of bundling all the dependencies that you might install using npm. You just need to expose the component to the window by exporting it so that it can then be accessed by step 2.
You could then use a <script> to load the component bundle you need in a specific template and then render it using ReactDOM.render(React.createElement(YourComponent), document.getElementById('the-container')).
If you're not familiar with Webpack you can take a look at this article: https://www.valentinog.com/blog/webpack/#how-to-set-up-react-webpack-5-and-babel-from-scratch
I did not test this so I'm not sure it works but as I said I thought it was an interesting question and I want it to give it a go and maybe give you some useful ideas.
I receive an error whenever I import a library in my index.js file and try to use it in index.html file.
script tag in index.html:
<script src="index.js" type="module"></script>
import statement in index.js: import axios from './node_modules/axios';
The error I receive:
*I am running the app on a local server, not on the file system.
if you use just vanilla JavaScript and you want to use module you have to add in script tag type module for index.js by this way you tell browser you have to support module in index.js, and after you use module normally with exception you have to add extension name like ".js" for each import Good Luck
<script type="module" src="main.js"></script>
You need to provide the URL to an ES6 module file, not the URL to an automatically generated HTML document showing an index of files in the axios directory.
The Axios distribution includes:
node_modules/axios/dist/axios.min.js
… but that appears to be a hybrid "Load with a regular script tag in the browser" and CommonJS module — not an ES6 module, so you can't import it.
Consider using a tool like Webpack instead.
You can use CDN instead of that.
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.min.js"></script>
Thank you
I've been trying to sort this out for a while; my goal is to use Polymer modules inside the Aurelia framework. There's a tutorial here (on the official documentation), but that's not for a CLI generated app.
my aurelia.json file has the following dependencies:
…
"aurelia-html-import-template-loader",
"aurelia-polymer",
…
(installed using npm)
and the index.html file looks like this:
<head>
<title>Aurelia</title>
<script src="bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="bower_components/polymer/polymer.html">
…
I have no errors in the CLI/console upon building.
main.js
aurelia.use.plugin('aurelia-polymer');
loads fine but
aurelia.use.plugin('aurelia-html-import-template-loader');
gives errors in the browser console:
vendor-bundle.js:21513 GET http://localhost:9000/app.html
Unhandled rejection Error: Load timeout for modules: template-registry- ………
I've been talking to a bunch of lads on aurelia/gitter, but so far I've found nobody who was able to get 'aurelia-html-import-template-loader'working in the CLI.
Thanks for reading,
have an awesome day
From aurelia-polymer:
Using with Webpack
If you're using webpack, you won't be able to use
aurelia-html-import-template-loader, which means you won't be able to
load Polymer elements in your templates directly (see #18). Instead,
it's suggested that you use vulcanize to bundle all the Polymer
elements you use into one file that can be loaded in index.html. The
elements will still be available in your templates once loaded, but
this avoids the syntax issues that require the HTML import template
loader.
I haven't tried it with aurelia-cli yet, but it's worth a shot.
I've installed ReactJS and Babel using npm in my laravel project. They are found in "node_modules" folder created by npm itself. But the problem is my react code doesn't seem to work if I import using this code:
<script src="node_modules/react/react.js"></script>
<script src="node_modules/react-dom/dist/react-dom.js"></script>
<script src="node_modules/babel-core/lib/api/browser.js"></script>
Is the format of the path correct? because if I just import using this type of code for all my imports required for ReactJS:
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/react.js"></script>
It seems to work if I just use the internet for getting the packages.
My react code is here:
<div id="myapp"></div>
<!-- JavaScripts -->
<script type="text/babel">
var BuckyComponent = React.createClass({
render: function() {
return(
<h2>{this.props.user} likes to eat {this.props.food}</h2>
);
}
});
React.render(
<div>
<BuckyComponent user="Arth" food="Bacon"/>
<BuckyComponent user="Arth" food="Pork"/>
<BuckyComponent user="Arth" food="Chicken"/>
</div>,
document.getElementById('myapp')
);
</script>
That's not the way you use Npm/Bower packages within Laravel. Either package manager will store its files outside the Laravel public folder, the first inside node_modules and the later inside bower_components. So they're not intended to be publicly available.
So how would you use their packages within Laravel? Using build systems like Laravel Elixir, just the Gulp or even the Grunt.
It's all up to you to copy the distribution files of React and Babel, concat them, minify them and the like. You'll end up with them inside the public folder, but before you'll want to do a nice concatenation and minification of all that stuff to serve the smallest possible number of files and their sizes.
I am using react starter kit for client side programming. It uses react and webpack. No index.html or any html to edit, all js files. My question is if I want to load a vendor js lib from cloud, how to do I do that?
It would be easy to do that in a html file. <script src="https://forio.com/tools/js-libs/1.5.0/epicenter.min.js"></script>
However, in js file, it only uses npm installed packages. How can I import the above lib with no html file? I tried import and require, they only work for local files.
update 10/21/15
So far I tried two directions, neither is ideal.
#minheq yes there is a html file sort of for react start kit. It is html.js under src/components/Html. I can put cloud lib and all its dependencies there like this:
<div id="app" dangerouslySetInnerHTML={{__html: this.props.body}} />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://forio.com/tools/js-libs/1.5.0/epicenter.min.js"></script>
<script src="/app.js"></script>
<script dangerouslySetInnerHTML={this.trackingCode()} />
</body>
Good news is it works, I don't need do anything else in js file, no import or require. However, now I have two jquery libs loaded in different ways. One in here, the other through npm and webpack. I wonder it will give me trouble later. The react-routing I use give me 'undefined variable' error if I type a none home path in browser window due to the server side loading I guess. So this solution is not very good.
Use webpack externals feature. This is documented as: link. "You can use the externals options for applications too, when you want to import an existing API into the bundle. I.e. you want to use jquery from CDN (separate tag) and still want to require("jquery") in your bundle. Just specify it as external: { externals: { jquery: "jQuery" } }."
However, the documentation I found a few places are all fussy about how to do this exactly. So far I have no idea how to use it to replace <script src="https://forio.com/tools/js-libs/1.5.0/epicenter.min.js"></script> in html.
externals is not intended to let you do this. It means "don't compile this resource into the final bundle because I will include it myself"
What you need is a script loader implementation such as script.js. I also wrote a simple app to compare different script loader implementations: link.
var $script = require("scriptjs");
$script("//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js", function() {
$('body').html('It works!')
});
You can create a script tag in your JS as
$("body").append($("<script src="https://forio.com/tools/js-libs/1.5.0/epicenter.min.js"></script>"))
There is one html file that is definitely being used to serve to users with your js bundle attached. Probably you could attach the script tag into that html file
Use webpack's externals:
externals allows you to specify dependencies for your library that are
not resolved by webpack, but become dependencies of the output. This
means they are imported from the environment during runtime.
I have looked around for a solution and most of all proposals were based on externals, which is not valid in my case.
In this other post, I have posted my solution: https://stackoverflow.com/a/62603539/8650621
In other words, I finished using a separate JS file which is responsible for downloading the desired file into a local directory. Then WebPack scans this directory and bundles the downloaded files together with the application.