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

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"]
}
}
};

Related

I am trying to access a folder outside of the current directory of my folder in express js

Their is two folders inside my folder one is made up for front-end and one is for back-end
project
├── back-end
│ ├── public
│ └── routes
│ ├── Calling.js
│ └── index.js
└── front-end
├── public
└── src
└── Components
└── Contact.js
from back-end am trying to call front end file by using sendFile()
app.get('/', function(req,res,next){
res.sendFile(path.join(
__dirname,
'../back-end',
'/front-end/src/Components/Contact'
))
})
while am running (npm start) the folder is not switch back to front-end,It is considering as a folder of back-end and showing no such file directory
Here is the error message
ENOENT: no such file or directory, stat 'D:\Project\back-end\routes\front-end\contact-form\src\Components\Contact'
I fixed this isuue by using
res.sendFile(path.format({
dir: 'D:\\Project\\front-end\\src\\Components',
base: 'Contact.js'
}))
Here I used
(path.format({dir:'path_of_file',base:'name_of_file'}))
Path.join does not combine the contents of two files, it combines two filesystem paths into a single path.
If you want to combine the contents of both files, you must read the contents of each file separately and then concatenate them together.
You want FS.readFile( path, options ).

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.

How to include library files (css/js) in angular-fullstack based app

I used a Yo Angular-Fullstack generator (https://github.com/DaftMonk/generator-angular-fullstack) and started an app and then tried installing Toastr from bower by doing -
bower install angular-toastr
and now I want to add the toastr css and js files. They are located in the
bower_components/angular-toastr/dist
now how do i include them in my current project, so that they are included in the dist folder when i build the application using grunt.
The folder structure is as follows -
├── client
│ ├── app - All of our app specific components go in here
│ ├── assets - Custom assets: fonts, images, etc…
│ ├── components - Our reusable components, non-specific to to our app
│
├── e2e - Our protractor end to end tests
│
└── server
├── api - Our apps server api
├── auth - For handling authentication with different auth strategies
├── components - Our reusable or app-wide components
├── config - Where we do the bulk of our apps configuration
│ └── local.env.js - Keep our environment variables out of source control
│ └── environment - Configuration specific to the node environment
└── views - Server rendered views
I use a grunt task called wiredep. It looks for the bower components that my app uses and add a reference to the css/js files to the file I specify.
I'm using .NET BundleConfig for minification so my task setup looks like this:
wiredep: {
task: {
src: [
'App_Start/BundleConfig.cs'
],
ignorePath: '..',
fileTypes: {
cs: {
block: /(([ \t]*)\/\/\s*bower:*(\S*))(\n|\r|.)*?(\/\/\s*endbower)/gi,
detect: {
js: /<script.*src=['"](.+)['"]>/gi,
css: /<link.*href=['"](.+)['"]/gi
},
replace: {
js: '.Include("~{{filePath}}")',
css: '.Include("~{{filePath}}")'
}
}
},
dependencies: true,
devDependencies: false
}
},
The end result is something like this:
bundles.Add(new ScriptBundle("~/bundles/thirdparty")
//NOTE: auto-generated by a grunt task
//anything between 'bower:js' and 'endbower' WILL BE LOST!
//bower:js
.Include("~/assets/angular/angular.js")
.Include("~/assets/moment/moment.js")
//endbower
);
bundles.Add(new StyleBundle("~/bundles/css")
//NOTE: auto-generated by a grunt task
//anything between 'bower:css' and 'endbower' WILL BE LOST!
//bower:css
.Include("~/assets/nouislider/distribute/nouislider.min.css")
//endbower
.Include("~/Content/css/app.css")
);
As I said, I'm using .NET BundleConfing, However, you can use and tags. I think you just need to remove the option replace from the grunt task configuration.

Setting up react-bootstrap simple app

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.

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