Setting up react-bootstrap simple app - javascript

I am setting up a getting-started app using react-bootstrap + requirejs + bower + php ( not nodejs). Very new to this spectrum of tools. so here is my app:
.bowerrc
{
"directory": "javascript/components/",
"analytics": false,
"timeout": 120000
}
bower.json
{
"name": "hello-react-bootstrap",
"version": "1.0.0",
"dependencies": {
"requirejs": "*",
"react": "~0.13.1",
"react-bootstrap": "~0.20.0"
}
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Hello World</title>
<!-- Bootstrap Core CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"/>
<!-- Require Js -->
<script data-main="javascript/setup.js" src="javascript/components/requirejs/require.js"></script>
</body>
</html>
javascript/setup.js
requirejs.config({
baseUrl: "javascript/components",
paths: {
"app": "../app",
'classnames':'classnames/index',
'jquery': 'https://code.jquery.com/jquery-2.1.3.min',
'react':'react/react',
'react-bootstrap':'react-bootstrap/react-bootstrap'
}
});
require.config({
urlArgs: "bust=" + (new Date()).getTime()
})
requirejs(["app/main"]);
javascript/app/main.js
//empty for now
application structure
── bower.json
├── index.html
├── javascript
│   ├── app
│   │   └── main.js
│   ├── components
│   │   ├── classnames
│   │   ├── react
│   │   ├── react-bootstrap
│   │   └── requirejs
│   └── setup.js
└── styles
I tried sth like this:
app/main.js
define(['react-bootstrap'], function(ReactBootstrap){
var React = require('react');
var Button= ReactBootstrap.Button;
React.render(Button,document.body)
});
which gives me :
Error: Invariant Violation: React.render(): Invalid component element. Instead of passing a component class, make sure to instantiate it by passing it to React.createElement.
Edit
Disregard my question following is working for me :
app/main.js
define(['react-bootstrap'], function(ReactBootstrap){
var React = require('react');
React.render(React.createElement(ReactBootstrap.Button,{bsStyle:'info'},'Hello World' ), document.body)
});

If you want to use JSX syntax in your main.js, you have to compile it. Otherwise, you only can use the React API to create your element, such as React.createElement. The react starter guide covers the concept.
I suggest you can use Babel which is already adopted in the official react repository to transform your code. Install the babel as a CLI: npm install -g babel. Let's say you put all your js in app/ folder, and execute babel app --out-dir build. It means you scan all js files under app folder and transforms them to build/ folder.
Then, modify your entry point path in javascript/setup.js. Change requirejs(["app/main"]); to requirejs(["build/main"]);. It includes the transformed js files.
If you want to apply ES2015 (a.k.a ES6) to write better js, just add params to the babel CLI to compile the ES2015 modules to the module system you use. You use RequireJS, so the command will be: babel src --out-dir build --modules amd.

Related

Vue CLI 3 SPA in Subfolder, Static HTML Pages in Root

Using Vue CLI 3 how can I create a project that contains some static html files at the root of the public directory and an SPA inside of an app folder?
I'd like several static html files including an index.html at the root of the project. I want these static HTML files served outside of the SPA for SEO purposes.
Right now, my project structure looks like this:
.
├── README.md
├── babel.config.js
├── package.json
├── public
│   ├── app
│   │   └── index.html
│   ├── favicon.ico
│   └── index.html
├── src
│   ├── App.vue
│   ├── assets
│   │   └── logo.png
│   ├── components
│   │   └── HelloWorld.vue
│   └── main.js
├── vue.config.js
└── yarn.lock
I've tried many different combinations of publicPath and indexPath values in my vue.config.js file. None have achieved what I'm hoping for. I'd like yarn serve to serve both the static HTML files and SPA locally for development. More importantly, I'd like the static HTML files and the SPA properly bundled into the dist folder when I run yarn build. I haven't been able to achieve either goal.
With the configuration below, the public/index.html file that's meant to be static and only displaying at / is being served at both http://localhost:8080/ and http://localhost:8080/app/. Interestingly, at http://localhost:8080/app/ the js resources are being injected into the response along with what's meant to be static HTML.
After running yarn build with the config below I'm left with a /dist/app/index.html file that has the static index.html file code with no javascript injected instead of the SPA code with javascript injected. The /dist/index.html file has the static HTML I expect but all the javascript that's meant for the SPA is injected.
// vue.config.js
module.exports = {
publicPath: '/app/',
indexPath: 'index.html'
}
How can I configure this project to support static html files at the project root and an SPA in the app folder?
You can leverage the feature of Vue CLI to build multipage apps and actually have only one page...
// vue.config.js
module.exports = {
pages: {
index: {
// entry for the page
entry: "src/main.js",
// the source template
template: "public/app/index.html",
// output as dist/app/index.html
filename: "app/index.html",
// when using title option,
// template title tag needs to be <title><%= htmlWebpackPlugin.options.title %></title>
title: "App Index Page",
// chunks to include on this page, by default includes
// extracted common chunks and vendor chunks.
chunks: ["chunk-vendors", "chunk-common", "index"]
}
}
};

typescript import with node

I'm just starting with front-end web developpement(javascript hell with all these package manager/bundler) and I'm trying to use typescript + browsify
so I create a index.ts file and download the uniq module(using npm) just to test ts file compilation
here is my index.ts
/// <reference path="node_modules/uniq/uniq.d.ts" />
import {unique} from "uniq";
var data = [1, 2, 2, 3, 4, 5, 5, 5, 6];
console.log(unique(data));
uniq.d.ts
// Type definitions for uniq
// Project: https://www.npmjs.com/package/uniq
// Definitions by: Hans Windhoff <https://github.com/hansrwindhoff>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
interface Uniq{
<T>(ip:Array<T>): Array<T>;
}
declare var uniq :Uniq;
declare module "uniq" {
export = uniq;
}
directory structure
.
├── entry.ts
├── node_modules
│   └── uniq
│   ├── LICENSE
│   ├── package.json
│   ├── README.md
│   ├── test
│   │   └── test.js
│   ├── uniq.d.ts
│   └── uniq.ts
└── package.json
but when I try to compile the index.ts I got this error :
error TS2688: Cannot find type definition file for 'uniq'.
First
you probably have the path wrong:
/// <reference path="node_modules/uniq/uniq.d.ts" />
Maybe ../../node_modules/uniq/uniq.d.ts. Instead of britle paths like this please use tsconfig.json : https://basarat.gitbooks.io/typescript/content/docs/project/tsconfig.html
Second
Based on the .d.ts you showed your import import {unique} from "uniq"; is also wrong. It should be import unique = require('uniq') since its a single function export. You will get an error about this anyways after you fix first. Enjoy 🌹

Copy NPM module/library to distribution folder using Gulp

Most web applications these days include various prebuilt libraries e.g. Backbone.js.
I want, when I compile my web application with Gulp, to output a single compressed JavaScript file of the library/module I installed using NPM e.g. backbone-min.js.
For example, when you install Backbone.js from NPM the following is installed into the node_modules folder:
.
├── backbone
│   ├── LICENSE
│   ├── README.md
│   ├── backbone-min.js
│   ├── backbone-min.map
│   ├── backbone.js
│   └── package.json
I want to be able to run gulp compile and get the following result in my web application distribution folder:
.
├── index.html
├── scripts
│   ├── backbone-min.js // this is the file I want to copy or generate
│   ├── main.min.js
The way I see it Gulp either needs to either:
compile and minify the library/module and write it to a file called backbone-min.js to the scripts folder, or
copy the backbone-min.js in the backbone module folder to the scripts folder.
What is the best way of doing this?
Short Answer
gulp-useref concatenates all the file references in your main .html file encapsulated by <!--build:js /lib.js--> for javascript files and <!--build:css /lib.css--> followed by <!--endbuild-->
The result will be:
index.html
├── scripts
│ ├── backbone-min.js // this is the file I want to copy or generate
│ ├── main.min.js
as you and every good developer wants it to be.
Long Answer
My recommendation would be to use Bower as your app dependencies manager and npm as your development dependencies manager.
Use gulp-wiredep to automatically inject dependencies as you install/uninstall them and that way you don't have to maintain library css and js files in your index.html.
Uset gulp-inject to automatically inject your own css and js files as your add/remove them. This will result in never ever having to maintain application dependencies manually.
With wiredep, inject and useref you never have to touch your dependencies again.
This is what my index header and end of body look like:
<!---------------------------- Bower Managed Styles ----------------------------->
<!--build:css css/lib.css-->
<!--bower:css-->
<link rel="stylesheet" href="../bower_components/..."
<!--endbower -->
<!--endbuild -->
<!---------------------------- Application Styles ------------------------------->
<!--build:css css/app.css-->
<!--inject:css-->
<link rel="stylesheet" href="content/css/bootstrap ..."
<!--endinject-->
<!--endbuild-->
<!--------------------------- Bower Managed Javascript ------------------------->
<!--build:js js/lib.js-->
<!--bower:js -->
<script src="../bower_components/ ..."> </script>
<!--endbower -->
<!--endbuild -->
<!-------------------------- Application Javascript --------------------------->
<!--build:js js/app.js-->
<!--inject:js-->
<script src="app/ ..."> </script>
<!--endinject-->
<!--inject:templates:js-->
<!--endinject-->
<!--endbuild-->
The comments are tags used by the tools I just mention in order for them to know where to insert the dependencies of interest.
My application entry is a single template reference. Needless to say I never visit index.html. I never have a reference to a file that does not exist. I never have a file that does not have a reference.

express.js (static server) isn't loading my javascript

My I'm using express.js as a static server and the code is looking like this:
var express = require('express'),
app = express();
app
.use(express.static('./public'))
.get('*', function (req, res) {
res.sendfile('public/main.html');
})
.listen(3000);
My file structure:
.
├── bower_components
│   ├── angular
│   ├── bootstrap
│   └── jquery
├── node_modules
│   └── express
├── public
│   ├── main.html
│   ├── src
│   └── views
└── server.js
My HTML is looking like this:
<!DOCTYPE html>
<html ng-app="ContactsApp">
<head lang="en">
<meta charset="UTF-8">
<title> Contacts </title>
<base href="/" />
<link rel="stylesheet" href="src/bootstrap.min.css"/>
</head>
<body>
<script src="../bower_components/jquery/dist/jquery.min.js"></script>
<script src="../bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="../bower_components/angular/angular.min.js"></script>
<script src="src/app.js"></script>
</body>
</html>
The Browser is not loading the angular library und I'm getting a error Resource interpreted as Script but transferred with MIME type text/html: "http://localhost:3000/bower_components/angular/angular.min.js"..
What I'm doing wrong? I couldn't find any answers from the previous questions.
This line says that you are serving your static files from ./public
use(express.static('./public'))
So only this tree will be exposed to the public:
├── main.html
├── src
└── views
Your bower_components diretory is not in public, thus it is not exposed.
To fix this, you can create a .bowerrc file in the root of your application with the following:
{
"directory": "public/bower_components/"
}
It will tell to bower to install the bower components in public instead of the default bower_components directory. Just run bower install after creating this file, and don't forget to update your index.html with the updated paths.
EDIT: Dont be tempted to change use(express.static('./public')) by use(express.static('./')) cause it will easily resolve your issue. It will expose your whole directory structure (and all your files) and is not good for obvious security reasons :)

How to optimize all javascript files in a directory with requirejs

I have a folder structure like this:
.
├── autocomplete
│   ├── core.js
│   ├── search.js
│   └── user.js
├── build.js
├── collapsible_lists.js
├── griffgrabber
│   ├── canvasobject.js
│   ├── cargame.js
│   ├── car.js
│   ├── griffDrawer.js
│   ├── keylistener.js
│   ├── run.js
│   └── victim.js
├── main.js
├── newsfeed.js
├── require.js
├── shortcut.js
└── sidebar.js
3 directories, 20 files
main.js is the startup file. That file requires a couple of the files, but not all of them. The rest of the files are included with
<script>
require(['shortcut'], function(shortcut){
// ...
})
</script>
in some html files.
This is my build.js file so far:
{
baseUrl: ".",
name: "main",
out: "main-built.js",
}
But it only includes the files that are required by main.js. Is it possible to optimize all the javascript files in one run?
(to expand #Ryan Lynch's suggestion):
Use the include option, as per the documentation:
You can always explicitly add modules that are not found via the optimizer's static analysis by using the include option.
(http://requirejs.org/docs/optimization.html)
{
baseUrl: ".", // ?
appDir: ".", // ?
dir: "output/",
modules: [
{
name: "main",
include: [ "shortcut" ]
}
]
}
More detailed example in the excellent example.build.js (I actually find it more useful than the documentation page)
(sorry, had no time to replicate and test properly to make sure the paths values are correct, I'll try that later and update my answer)
Try including a modules array in your options, so:
{
baseUrl: ".",
out: "main-built.js",
modules: [
{
name: "main"
}
]
}
As per the documentation:
In the modules array, specify the module names that you want to
optimize, in the example, "main". "main" will be mapped to
appdirectory/scripts/main.js in your project. The build system will
then trace the dependencies for main.js and inject them into the
appdirectory-build/scripts/main.js file.
Another - less orthodox - way of achieving this would be to add this "shortcut" module as a dependency to any of the "visible" modules that are discovered by r.js scanning (i.e. "main.js"). This way the entire dependency branch starting at "shortcut" would be included in the output.

Categories

Resources