Grunt compile external JS into inline HTML - javascript

Is it possible to take code from an external JS file, then paste it inline into script tags (in index.html), once the application is built?
For example, both files below are intended to be identical but I'd like the JS to be implemented externally in the src/dir and inline within the build/dir:
src/index.html
<head>
<script src="long/minified/code.js"></script>
</head>
build/index.html
<head>
<script>
// long... minified code to be added inline here
</script>
</head>
long/minified/code.js
(function(){var this,isSomeLong='minifiedCode';})();
Gruntfile.js
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
dist: {
src: [
'long/minified/code.js',
],
dest: 'build/index.html',
}
});
It's possible I'm completely off and need something like grunt-include-source

You can use grunt-processhtml to easily inline your scrips:
HTML
<head>
<!-- build:js inline -->
<script src="long/minified/code.js"></script>
<!-- /build -->
</head>
Gruntfile task:
grunt.initConfig({
processhtml: {
dist: {
files: {
'build/index.html': ['src/index.html']
}
}
}
});

Related

Vue CLI - combine build output to a single html file

I have a vue project created with vue-cli. The normal output when running yarn build is a dist folder with an index.html and a js and css sub-directory with the corresponding .js and .css files.
I want the build output to be a single html file that contains the js and css.
I added a vue.config.js file in the root of my project and set it to output a single js file and that is working ok. But I want to only have a single html file with the js and any css already on the html file.
module.exports = {
css: {
extract: false,
},
configureWebpack: {
optimization: {
splitChunks: false
}
}
}
Basically I want my html file to be something like this:
<html lang=en>
<head>
... meta tags
<title>my title</title>
</head>
<body>
<div id=app></div>
<script>
// contents of the output js file here
</script>
</body>
</html>
Is this possible?
Using Vue 3.9.3
Someone answered with a suggestion to look into html-webpack-inline-source-plugin but removed their answer. But that was exactly what I needed to get this done.
The plugin is not Vue or Vue-CLI specific but it works if you do the following:
1) Add a vue.config.js file in the root of the app.
2) The linked plugin above is actually an extension of another package. You need both.
npm install --save-dev html-webpack-plugin
npm install --save-dev html-webpack-inline-source-plugin
3)
// vue.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin')
const HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin');
module.exports = {
css: {
extract: false,
},
configureWebpack: {
optimization: {
splitChunks: false // makes there only be 1 js file - leftover from earlier attempts but doesn't hurt
},
plugins: [
new HtmlWebpackPlugin({
filename: 'output.html', // the output file name that will be created
template: 'src/output-template.html', // this is important - a template file to use for insertion
inlineSource: '.(js|css)$' // embed all javascript and css inline
}),
new HtmlWebpackInlineSourcePlugin()
]
}
}
4) Add a template. This is necessary for working in the Vue context because without this the output html file by default won't have the necessary <div id="app"></div> and Vue won't mount to anything. I basically took the normal output html file and modified it a little.
<!-- output-template.html -->
<!DOCTYPE html>
<html lang=en>
<head>
<meta charset=utf-8>
<meta http-equiv=X-UA-Compatible content="IE=edge">
<meta name=viewport content="width=device-width,initial-scale=1">
<title>example title</title>
</head>
<body><noscript><strong>We're sorry but my example doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript>
<div id=app>
</div>
<!-- plugin will insert js here by default -->
</body>
</html>
Then build like normal and the output.html file will be in the /dist folder

Webpack: How to inject javascript into the HTML instead of separate JS file

Is there a way to have webpack inject the output into the HTML instead of a separate file?
<html>
<head>
</head>
<body>
<script type="text/javascript">
// webpack puts the output here
</script>
</body>
</html>
I had to use the html-webpack-inline-source-plugin. https://github.com/DustinJackson/html-webpack-inline-source-plugin
plugins: [
new HtmlWebpackPlugin({
inlineSource: '.(js|css)$' // embed all javascript and css inline
}),
new HtmlWebpackInlineSourcePlugin()
]

How to use minified javascript?

I have a grunt tasks to concat and minify all my javascript files into one single file and the javascript file is in dist folder. "dist/<%= pkg.name %>.min.js'"
"Gruntfile.js"
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON("package.json"),
concat: {
options: {
separator: ';'
},
dist: {
src: ['src/main/resources/app/js/**/*.js',
'src/main/resources/app/config/*.js',
'src/main/resources/app/app/js'],
dest: 'dist/<%= pkg.name %>.js'
}
},
uglify: {
options: {
banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
},
dist: {
files: {
'src/main/resources/app/dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.registerTask("default", ["concat", "uglify"]);
};
Now, how can I use this minified version of javscript? Moreover, my index.html entry point of my code points to the non-minified version.
"index.html"
<div ui-view/>
<script data-main="config/require-conf" src="vendor/requirejs/require.js"></script>
You could use usemin from https://www.npmjs.com/package/grunt-usemin. Usemin, with other tasks as
concat
uglify
cssmin
filerev
is able to minify all js and css in one single file. You only need to add a build:js as you can see in snippet below:
<!-- build:js SCLogic.min.js -->
<!-- Load app main script -->
<script src="app/app.js"></script>
<!-- Load services -->
<script src="app/services/authInterceptorService.js"></script>
<script src="app/services/authService.js"></script>
<script src="app/services/blablaService.js"></script>
<!-- Load controllers -->
<script src="app/controllers/indexController.js"></script>
<script src="app/controllers/homeController.js"></script>
<script src="app/controllers/loginController.js"></script>
<script src="app/controllers/blablaController.js"></script>
<script src="app/directives/validNumber.js"></script>
<script src="app/controllers/angular-locale_es-es.js"></script>
<!-- endbuild -->
You can just include the js file the normal way.
<script src="path to the minified file"></script>
in your index.html.
Minified file is just like a normal JS file. What it does is:
It will merge all the mentioned JS files into a single file.
It will then minify it i.e it will remove the white spaces and auto change the variable names.
Advantage of this is you will have a lower size file and a single http request made from your browser which will help you load the page at a faster speed.

usemin using wrong directory for input asset files

I'm attempting to get a gruntfile working to concatenate / uglify javascript files in a Laravel application. All of my tasks work in isolation, but for whatever reason the paths to my input javascript files are not being set correctly.
Here's an example of one of my blade templates:
#section('scripts')
<!-- build:js /js/min/page.min.js -->
<script type="text/javascript" src="/js/scrollIt.min.js"></script>
<script type="text/javascript" src="/js/jquery.omniwindow.js"></script>
<script type="text/javascript" src="/js/isotope.min.js"></script>
<!-- endbuild -->
#stop
Here's my useminPrepare / usemin task definitions:
useminPrepare: {
html: 'app/views/**/*.blade.php',
options: {
dest: 'app/views/dist'
}
},
usemin: {
options: {
assetDirs: [ 'public/js' ]
},
html: [ 'app/views/dist/**/*.blade.php' ]
},
I have no defined uglify task, I'm just relying on the one that usemin will generate.
All templates are making it into the 'app/views/dist' directory correctly, with the correct replacement (in the example above, there's a single javascript file at public/js/min/page.min.js being included in the template). During processing, I noticed output:
$ grunt build
Running "useminPrepare:html" (useminPrepare) task
Going through {list of templates} to update the config
Looking for build script HTML comment blocks
Configuration is now:
concat:
{ generated:
{ files:
[ { dest: '.tmp/concat/js/min/page.min.js',
src:
[ 'app/views/course/js/scrollIt.min.js',
'app/views/course/js/jquery.omniwindow.js',
'app/views/course/js/isotope.min.js' ] },
] } }
uglify:
{ generated:
{ files:
[ { dest: 'app/views/dist/js/min/page.min.js',
src: [ '.tmp/concat/js/min/page.min.js' ] },
] } }
cssmin:
{}
As you can see above, it is looking for my javascript files in app/views/course/js directory, which is incorrect. Why is this? I thought specifying assetDirs: ['public/js'] in my usemin task would tell grunt where to find those files. I have tried changing the script references to look like this:
<script type="text/javascript" src="../../../public/js/scrollIt.min.js"></script>
And this causes a successful build, but breaks my local development so its definitely not a solution. Do I need to somehow override the uglify:generated task, and if so, how do I do it for multiple different templates with generated filenames?
If it's necessary, you can see the entirety of my Gruntfile.js here. You can see from there I had to also add a new copy task for copying Javascript files from app/views/dist/js/min back over to public/js/min. I'd also like to get rid of that, but if I can just get around this issue I'd be happy.
The answer here actually turned out to be relatively simple, and was able to be gathered directly from the usemin documentation (as soon as I started to look hard enough):
Blocks are expressed as:
<!-- build:<type>(alternate search path) <path> -->
... HTML Markup, list of script / link tags.
<!-- endbuild -->
In my case for working with Laravel, I needed to specify an alternate search path of public/ and it wound up working just fine:
#section('scripts')
<!-- build:js(public/) /js/min/script.min.js -->
<script type="text/javascript" src="/js/script1.js"></script>
<script type="text/javascript" src="/js/script2.js"></script>
<script type="text/javascript" src="/js/script3.js"></script>
<script type="text/javascript" src="/js/script4.js"></script>
<!-- endbuid -->
#stop

why doesn't this simple require.js setup work?

I'm trying to learn how to use require.js to load my scripts, but something is wrong with my setup/understanding. I can't see what is wrong. It is something simple with the setup that I'm missing.
When I load this index.html page in chrome, none of the script require.js action is working.
***index.html
<html>
<head>
<title>My Sample Project</title>
</head>
<body>
<h1 class="h1">sample project header</h1>
<script data-main="main" src="require.js"></script>
</body>
</html>
***main.js
(function() {
requirejs.config({
//By default load any module IDs from baseUrl
baseUrl: '',
// paths config is relative to the baseUrl, and
// never includes a ".js" extension
paths: {
'small-blue-mod': './a-script'
}
});
// Start the main app logic.
requirejs(['small-blue-mod'], function (sbm) {
alert(sbm.color);
});
})();
***small-blue-mod.js
define({
color: "blue",
size: "small"
});
*File System looks like...
index.html
main.js
require.js
FOLDER called "a-script"
a-script folder contains small-blue-mod.js
The path small-blue-mod refers to the a-script folder, either require it like small-blue-mod/small-blue-mod or recommended change your path to this:
paths: {
'small-blue-mod': './a-script/small-blue-mod'
}

Categories

Resources