grunt-include-source doesn't work - javascript

I try to make a simple using of - grunt-include-source but I don't success -
My Gruntfile is -
module.exports = function (grunt) {
grunt.initConfig({
includeSource: {
options: {
basePath: 'app/file1.js'
},
myTarget: {
files: {
'dist/index.html': 'app/index.html'
}
}
}
});
grunt.loadNpmTasks('grunt-include-source');
grunt.registerTask('serve', function (target) {
grunt.task.run('includeSource');
});
}
The index.html is -
<html>
<head>
</head>
<body>
<!-- include: "type": "js", "files": "scripts/*.js" -->
</body>
</html>
My folder hierarchy is -
Gruntfile.js
app >
file1.js
index.html
dist >
index.html
I run grunt serve and get in the dist>index.html folder the output -
<html>
<head>
</head>
<body>
</body>
</html>
Without the expected - <script src="scripts/file1.js"></script>
I kept to follow as in the documentation and in this question ,
Why I don't get the expected output ?

You have two problems with your code, first in gruntfile you are specifying a wrong path, second on your html you are specifying a wrong source.
Let's go by parts, on your gruntfile you have this:
...
includeSource: {
options: {
basePath: 'app/file1.js'
},
...
The basepath option on the docs says:
Type: String or Array[String] Default value: ''
The base path to use when expanding files. Can be an array to support
expanding files from multiple paths.
What this allows us to do is including one or more paths as our base path for our scripts. So let's change our basePath to basePath: 'app', our Gruntfile.js will look like this:
module.exports = function (grunt) {
grunt.initConfig({
includeSource: {
options: {
basePath: 'app'
},
myTarget: {
files: {
'dist/index.html': 'app/index.html'
}
}
}
});
grunt.loadNpmTasks('grunt-include-source');
grunt.registerTask('serve', function (target) {
grunt.task.run('includeSource');
});
};
Now if we run grunt serve it won't work, why? Well because on your index.html you have this:
<!-- include: "type": "js", "files": "scripts/*.js" -->
Which means, insert script tags for all the javascript files, inside the scripts folder, but we don't have any scripts folder, so that's why your dist/index.html is empty. Let's change our index.html to this:
<!-- include: "type": "js", "files": "*.js" -->
Run grunt serve et voilĂ  your index.html has changed to:
<html>
<head>
</head>
<body>
<script src="file1.js"></script>
</body>
</html>
Now you just have to copy file1.js from app/ to dist/

Related

How to properly split common dependencies with webpack4

I am having difficulty configuring webpack4 to properly bundle shared dependencies.
I have two pages in my application (Page1 and Page2). Both require bootstrap, jquery as well as a custom JavaScript app called core.
Page 2 requires the same but also a custom JavaScript application called my-app and also lodash.
Since my core app will be included in all pages, I want to have jquery and bootstrap in the same bundle.
Since lodash is only required for pages running my-app, I want to include that dependency in the my-app bundle.
So I setup my app like this:
webpack.config.js
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: {
'core': './src/core/index.js',
'my-app': './src/my-app/index.js'
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
},
resolve: {
alias: {
jquery: 'jquery/src/jquery',
}
},
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
}),
],
mode: 'development',
}
page1.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Page1</title>
<script src="dist/core.bundle.js"></script>
</head>
<body>
<h1>Page1</h1>
<span id="test"></span>
</body>
<script>
$(document).ready(function() {
$('#test').text('jQuery Works!');
});
</script>
</html>
page2.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Page1</title>
<script src="dist/core.bundle.js"></script>
<script src="dist/my-app.bundle.js"></script>
</head>
<body>
<h1>Page2</h1>
<span id="test"></span>
</body>
<script>
$(document).ready(function() {
$('#test').text('jQuery Works!');
});
</script>
</html>
(Full project: https://github.com/LondonAppDev/webpack-split-example)
When I run npx webpack, it creates core.bundle.js and my-app.bundle.js, however both of these include jquery.
Is it possible to put all "global" dependencies in core.bundle.js?
Just one thing to remember here, with webpack 4 you don't add vendor scripts as an entry to your webpack.config, just real entry scripts to your application.
WP will create an optimized bundle output for your app using the default settings.
You have to add vendor cache group to your config, in order to extract jQuery, Lodash, Bootstrap,Popper into a separate bundle:
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
test: /node_modules/,
name: "vendor",
chunks: "all",
enforce: true
}
}
}
},

Cannot GET / with webpack-dev-server

How come I am getting Cannot GET / in my browser? I think it is because my webpack-dev-server does not have a route to GET the bundled files.
devServer/server.js
import config from '../../webpack.config';
import webpack from 'webpack';
import WebpackDevServer from 'webpack-dev-server';
import open from 'open';
// template! https://github.com/webpack/webpack-dev-server/blob/master/examples/node-api-simple/server.js
const compiler = webpack(config);
const server = new WebpackDevServer(compiler, {
contentBase: '../dist/',
stats: {
colors: true
}
});
server.listen(3000, '127.0.0.1' ,err => {
if (err) {
console.log(err);
} else {
console.log('Dev Server listening on port 3000!\n');
open("http://localhost:3000");
}
});
webpack.config.js
import webpack from "webpack";
export default {
entry: [
"./app/index"
],
devtool: "inline-source-map",
output: {
path: __dirname + "/app/dist/", // Note: Physical files are only output by the production build task `npm run build`.
publicPath: "/",
filename: "bundle.js"
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
],
module: {
rules: [
{ test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
options: {
presets: ['env', 'react']
}
}}
]
}
};
Project structure
On successful build a folder dist will be created inside the app folder which currently is not there.
Once the folder is created you can try by directly hitting the file path
http://localhost:3000/app/dist/yourfile
You can access your page via localhost:3000
When you access this path webpack dev server is searching for an index.html file to serve (like any other webserver). It can not find an index.html file because you have no index.html file. The index.html file is served from the static directory, which you have defined via property contentBase: '../dist/',.
but as I see you have no directory named dist and you have no index.html in this directory.
Your script is served from the public path, that is / in your config, so you have to reference this in your index.html
Solution:
Create directory dist and put an index.html file there with the following content:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script src="/bundle.js"></script>
</body>
</html>
For more information read here:
https://webpack.github.io/docs/webpack-dev-server.html

Webpack publicPath don't work

I have a demo like this:
my webpack config:
module.exports = {
entry: './app.js',
output: {
filename: 'bundle.js',
path: './build',
publicPath: 'http://localhost:3000/'
},
module: {
rules: [{
test: /static\.html/,
use: 'file-loader'
}, {
test: /\.png/,
use: 'file-loader?name=[name].[ext]'
}, {
test: /\.css/,
use: 'file-loader?name=[name].[ext]'
}],
},
resolveLoader: {
modules: ['node_modules'],
}
}
this is my entry app.js:
import './static.html';
import './img.png';
import './index.css';
static.html:
<!DOCTYPE html>
<html>
<head>
<title>static</title>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="./index.css">
</head>
<body>
<img src="./img.png">
</body>
</html>
when i run npm run build, i got a build folder. I think the build/static.html should be
<img src="http://localhost:3000/img.png">
<link href="http://localhost:3000/index.css">
But, actually the build/static.html is the same as static.html. Both of the src of img and the href of link are not changed.
Any one knows why?
====
I have known the answer. Webpack publicPath just work for output file. So just the url in the bundle.js will be replaced.
The webpackHtmlPlugin will not resolve this problem, because this plugin will generate a html page with a script links to the output bundle.js that I don't need it.
To resolve this problem, I have wrote a custom loader to transform the html page output by the file-loader dynamicly.
The file-loader would not change the file. If you want a html file with the publicPath added, you should use html-webpack-plugin.

Is there anyway to repeatedly grab `pkg.json` version as a variable to replace the version of `index.js` file in Grunt?

I have a grunt build. There are grunt-bump and grunt-replace in it. I use grunt-bump to bump up one version up in pkg.json every time I run it. And I'd also want to replace the index.js version with pkg.json version number every time when I run grunt-replace. However, I can't do it repeatedly because once the variable`##package gets replaced, the variable is no longer there.
Gruntfile.js:
module.exports = function(grunt) {
grunt.initconfig({
pkg: grunt.file.readjson('package.json'),
bump: {
options: {
files: ['package.json'],
updateconfigs: [],
commit: false,
commitmessage: 'release v%version%',
commitfiles: ['package.json'],
createtag: false,
tagname: 'v%version%',
tagmessage: 'version %version%',
push: false,
pushto: 'upstream',
gitdescribeoptions: '--tags --always --abbrev=1 --dirty=-d',
globalreplace: false,
prereleasename: false,
metadata: '',
regexp: false
}
},
replace : {
dist : {
options : {
patterns : [
{
match: 'packageJsonVersion',
replacement: '<%= pkg.version %>';
}
]
},
files : [
{
expand : true,
flatten : true,
src : [ 'index.html' ],
dest : './'
},
]
}
},
});
grunt.loadnpmtasks('grunt-bump');
grunt.loadnpmtasks('grunt-replace');
grunt.registertask('default', ['uglify']);
};
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script src="index.##packageJsonVersion.js"></script>
</body>
</html>
Usually, I have my base index.html file containing the variables to be replaced in my src folder but I actually copy the file and perform the replace in the build folder (or whatever folder is actually containing your prod static assets). This way, the base file is never altered.
Maybe you could change the dest and make your web server point to the prod version of your index.html?
files : [
{
expand : true,
flatten : true,
src : [ 'index.html' ],
dest : 'build/index.html'
},
]

qunit/browser works, but qunit/grunt fails with require.js

I've got a small github project with two branches: master (stable) and qunit-require (unstable). I've got some tests written in qunit that I want to have runnable both in the browser and from grunt level. On master branch everything works fine, travis-CI passes. And on qunit-require branch I'm trying to add require.js for the tests, but I didn't succeed yet.
I can run tests from the browser by displaying test/index.html. But when I run grunt in the console, I get no assertions error and I've got no idea why:
tducin#tducin-workshop:~/Development/tree (qunit-require)$ grunt
Running "qunit:all" (qunit) task
Testing test/index.html Warning: 0/0 assertions ran (15ms) Use --force to continue.
Aborted due to warnings.
I've got src/ and test/ directories as long as bower_components/ where bower deps are stored. This is my test/index.html:
<!DOCTYPE html>
<html>
<head>
<title>jsTreeStructure Test Runner</title>
<meta charset="utf-8">
<link rel="stylesheet" href="../bower_components/qunit/qunit/qunit.css" />
<script src="../bower_components/qunit/qunit/qunit.js"></script>
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<script src="../bower_components/requirejs/require.js" data-main="init.js"></script>
</body>
</html>
This is my test/init.js:
require.config({
baseUrl: '../',
shim: {
'underscore': {
exports: '_'
},
'tree' : {
exports: 'Tree'
},
'qunit' : {
exports: 'QUnit'
}
},
paths: {
'underscore': 'bower_components/underscore/underscore',
'qunit': 'bower_components/qunit/qunit/qunit',
'tree': 'src/tree'
}
});
require([
'test/suites/basic', 'test/qunit-extend'
], function(BasicTests) {
QUnit.config.autoload = false;
QUnit.config.autostart = false;
BasicTests.run();
QUnit.load();
QUnit.start();
});
and this is part of my Gruntfile.js:
/*global module:false*/
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
qunit: {
all: ['test/index.html'],
options: {
timeout: 3000,
coverage: {
src: ['src/tree.js']
}
}
},
// [...]
});
// These plugins provide necessary tasks.
grunt.loadNpmTasks('grunt-contrib-qunit');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-uglify');
// Default task.
grunt.registerTask('test', ['qunit', 'jshint']);
grunt.registerTask('build', ['uglify']);
grunt.registerTask('default', ['test', 'build']);
};
Anyway, you can find entire content at github: https://github.com/tkoomzaaskz/tree/tree/qunit-require
My question is: what can I do to make grunt execute the assertions (i.e. what mistake did I make here)?

Categories

Resources