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.
Related
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"]
}
}
};
I'm using Parceljs to bundle html and js. It works really well with less configuration.
Now, I'm facing i18n issue.
Google recommends using different URLs for each language version of a page.
https://support.google.com/webmasters/answer/182192
So, I want to generate language specific static html from one template like below.
.
├── dist
│ ├── ja
│ │ └── index.html
│ ├── app.c328ef1a.js
│ └── index.html
├── i18n
│ ├── default.json
│ └── ja.json
└── source
├── app.js
└── index.html
source/index.html
<html>
<body>
<h1>__TITLE__</h1>
<script src="/app.js"></script>
</body>
</html>
i18n/default.json
{
"__TITLE__": "Hello world!"
}
i18n/ja.json
{
"__TITLE__": "こんにちは 世界!"
}
Is there a way to deal with this issue using parceljs?
Or, should I write a code for prebuild?
Thank you.
Self answer:
I found a great answer here.
It mentions node-static-i18n package that generates i18n static HTML.
This tool isn't a plugin of parceljs, but it seems to be able to generate expected results.
Welcome yet another answer.
I just figured out that since I built my app with Next.js, I can't use CRA's folder structure framework to build or diagnose my application.
Unfortunately, I'm completely at a loss at the moment with respect to how Next.js applications are supposed to properly scale a website for mobile devices. I've always been under the impression that it was the job of index.html to do that (which I've written, but my app can't seem to bother to find it or use it). I've looked at the default folder structure for a Next.js app:
├── README.md
├── components
│ ├── head.js
│ └── nav.js
├── next.config.js
├── node_modules
│ ├── [...]
├── package.json
├── pages
│ └── index.js
├── static
│ └── favicon.ico
└── yarn.lock
source
but there doesn't seem to be a place for index.html.
My question is simply, how do Next.js apps optimize for mobile screens? Are they even supposed to have an index.html, and if so where? And how do favicons work, because I've created the static folder and put the favicon inside, but I'm pretty sure to have the favicon do anything, it has to be referenced by a file (conventionally index.html).
repo
Next has this Document component which you can customize to your own likings.
As their official docs say:
Is used to change the initial server side rendered document markup
You can use it to customize your head tag content as you would do anyway in your index.html.
Don't forget to add <meta name="viewport"content="width=device-width, initial-scale=1.0" /> in head tag if you want your app to use media queries.
Next project is not supposed to have a particular index.html file. Instead, the initial page is supposed to be a component located specifically in pages/index.js.
My problem lies in the next. I have a javascript application. It utilises the so called module pattern. That is I have multiple js files (one for each class) and during the build process all these files are put to a single file and wrapped in the IIFE. So in my karma config file I specify
files: ['src/**/*.js', 'tests/**/*.js']
The problem arises because I need to use several "modules" in this app. Here is the example of the tree structure of the code:
├── karma_unit.conf.js
├── src
│ ├── Bar
│ │ └── module.js
│ └── Foo
│ └── module.js
└── tests
└── unit
├── Bar
│ └── test.js
└── Foo
└── test.js
So I have two Module classes at the same time. This is not the problem with the "built" code. But for the unit tests this is the problem, because this is the name conflict.
I know that I can have different config files for each such a module and run tests several times (one per a single config file), but this is very undesirable.
Also I supposed that files are executed with respect to their inclusion order, so I tried to write in the config file:
files: [
'src/Foo/*.js',
'tests/Foo/*.js',
'src/Bar/*.js',
'tests/Bar/*.js',
]
But this did not help.
So my question is: how can I circumvent this situation when I'm forced to have several javascript classes with the same name in a single project without running tests several times or renaming these classes?
My appreciation in advance.
This is the reference link that details a solution for your query:
http://karma-runner.github.io/0.8/plus/RequireJS.html
I have the following directory structure for my ember application:
neuter/
├── adapters
├── controllers
├── models
├── routes
└── views
In all those directories I have lots of files. Currently, my neuterapp.js has lots of statements like:
require('app/neuter/models/node');
require('app/neuter/controllers/nodes');
I would like to avoid having to explicitly list all files which are needed. I have tried with:
require('app/neuter/controllers/*');
And with:
require('app/neuter/controllers');
But this is not working. Is there any way to require everything in a directory?
You could try:
require('app/neuter/models/**/*')
This addition was added with this merged PR.
Hope it helps.