I am currently in the process of writing my first Node.js app. I recently installed bootstrap via the npm (following instructions on bootstrap's web site) and was wondering the "standard" way of referencing the bootstap.min.css (and other files of interest). It is best to use grunt/gulp to copy (bundle and minify) the resources I need into my project structure?
Any help would be appreciated.
I was able to copy with the node_modules bootstrap resources with a simple Grunt task:
copy: {
bootstrapSrcCss: {
src: "./node_modules/bootstrap/dist/css/bootstrap.css",
dest: "./public/src/css/bootstrap.css"
},
bootstrapSrcJs: {
src: "./node_modules/bootstrap/dist/js/bootstrap.js",
dest: "./public/src/js/bootstrap.js"
}
}
Using grunt plug-in: grunt-contrib-copy
As explained in This Blog Post, you can create a "Static Route" instead of exposing the node_modules structure totally.
app.use('/scripts', express.static(__dirname + '/node_modules/bootstrap/dist/'));
But that may not be the best method. It seems that packages that come with resources also come with Grunt files as well.
Related
I am using Grunt's ['processhtml', 'uglify', 'concat', 'htmlmin', 'cssmin'] plugins to automate my web development. Works great. My question is regarding required directories. I currently have
source/
/includes
header.html
footer.html
index.html
about.html
staging/
(this gets auto populated by grunt with built prettified source files
public/
(this gets auto populated by grunt with uglified production ready code
Do I need a staging folder? Is this normal/standard usage? Or, can I / should I place prettified built out files straight in the public folder and then have the uglify task source AND destination be the public folder? Hope my question makes sense.
Thanks in advance.
I am trying (in vain) to get fonts working locally.
I have installed https://github.com/components/font-awesome and there is a line at the bottom of the page that states:
Here is the important part, the default font folder is on different path with the compiled bower file. We need to move the font from default font folder to the compiled bower folder (In the example vendor is the compiled folder).
Now I am using grunt, not gulp and I am also using the sass.
So, in my sass I have done this:
#import "../../bower_components/components-font-awesome/scss/fa-brands";
#import "../../bower_components/components-font-awesome/scss/fa-regular";
#import "../../bower_components/components-font-awesome/scss/fontawesome";
Which pulls in the correct fa fonts, etc.
Then following that text above I created a rule in my gruntfile that does this:
fonts: {
expand: true,
cwd: 'bower_components/components-font-awesome/webfonts/',
src: '*',
dest: '<%= yeoman.app %>/fonts'
}
But when I try to load my site using grunt serve -o I get this message:
Failed to decode downloaded font: http://localhost:9000/webfonts/fa-regular-400.woff2
So I can see it is looking in a different directory, so first of all I just added this to my sass:
$fa-font-path: "/fonts";
But that didn't work either.
So then I decided to change the copy rule to actually copy to /webfonts and still no icons were downloaded.
I have read some posts (with people with similar issues) and they have said the path was relative.
So I decided to copy the fonts and directories to everywhere they might need to be:
/webfonts
/assets/webfonts
/styles/webfonts
/fonts
Even doing that, no fonts are loaded.
Surely someone knows how to fix this?
I have a simple ASP .NET 5 empty project - with npm and grunt installed.
I've used npm to install a few client-side libraries, at present located in the node_modules directory directly under my ASP .NET project.
I want to copy the relevant files (for example, jquery.min.js) from the node_modules folder into the wwwroot folder.
It's unclear to me how to use grunt to do this - as each node module has it's own dependency tree, and there doesn't seem to be any consistency in the file structure from package to package.
I could write a grunt task explicitly for each client side library I use, but in that case I may as well download everything manually and place the files where I need them manually, avoiding npm all together.
I know I could use bower, which has a flat dependency tree - which is probably the root I should go down - but I've read a few articles saying "there's no need for bower - npm can do it all" and therefore I would like to know if there's a way to do this purely with npm.
Is there a way? Or is the "npm can do it all" statement aimed at projects that will require the components directly from the node_modules?
TL DR; Is bower a better fit than npm for ASP .NET 5 projects with separation of source and build files, and if not, what's the recommended way of doing it purely with npm?
I don't fill me professional in grunt, but I use it myself and I think that I can explain you how one can use it corresponds to your requirements.
First of all you should add "New Item" to your project, choose "Client-Side" and "NPM Configuration file" to add package.json to the the project (in the same directory where you have project.json). I suppose you have already created the file, but the existence of the file is important for grunt too. Then you adds some dependencies, which you need on the client-side to "dependencies" part of package.json and add at least grunt and grunt-contrib-copy to "devDependencies" part. An example of the file you will see below
{
"version": "1.0.0",
"name": "ASP.NET",
"private": true,
"dependencies": {
"font-awesome": "^4.5.0",
"jquery": "^1.11.3"
},
"devDependencies": {
"grunt": "^0.4.5",
"grunt-contrib-clean": "^0.7.0",
"grunt-contrib-copy": "^0.8.2"
}
}
Now you should add "Grunt Configuration File" in the same way like you added "NPM Configuration file". You will create gruntfile.js (in the same directory where you have project.json). Finally you should fill gruntfile.js with more helpful code. For example the code
module.exports = function(grunt) {
grunt.initConfig({
clean: ["wwwroot/font-awesome/", "wwwroot/jquery*.*"],
copy: {
main: {
files: [
{
src: "node_modules/font-awesome/css/*",
dest: "wwwroot/font-awesome/css/",
expand: true,
filter: "isFile",
flatten: true
},
{
src: "node_modules/font-awesome/fonts/*",
dest: "wwwroot/font-awesome/fonts/",
expand: true,
filter: "isFile",
flatten: true
},
{
src: "node_modules/jquery/dist/*",
dest: "wwwroot/",
expand: true,
filter: "isFile",
flatten: true
}
]
}
}
});
grunt.loadNpmTasks("grunt-contrib-clean");
grunt.loadNpmTasks("grunt-contrib-copy");
grunt.registerTask("all", ["clean", "copy"]);
grunt.registerTask("default", "all");
};
registers two tasks: clean and copy and the aliases all and default. You can select gruntfile.js file in the solution explorer, open context menu and choose "Task Runner Explorer". You will see all defined tasks. The task with the name "default" will be executed if you execute grunt without parameters (without the task name) in the command line.
Now you can choose some task and run it. You can choose some task, click right mouse button to open context menu and check "After Build" in "Bindings":
Now the task will be executed every time when you build the project. You can click optionally "V" button on the left side to see verbose information from the executed tasks.
I hope it's already the main information which you need. Many other helpful information about plugins grunt-contrib-clean, grunt-contrib-copy, grunt-contrib-jshint, grunt-jscs, grunt-newer and many other you will find yourself. One official place of ASP.NET 5 documentation should be mentioned. It's the place.
P.S. You asked additionally about the usage of bower. I find both npm and bower not perfect, but still very practical. I would prefer to hold full control over the dependencies and especially about the data, which will be copied under wwwroot. Thus I change the content of .bowerrc file from { "directory": "wwwroot/lib" } to { "directory": "bower_components" } and I use grunt to copy the required data from bower_components in the same way like I do this with files from node_modules. See the article for more details. In other words I use packages published only in bower repository in the same way like I use npm packages.
I'm using grunt + bower + grunt-bower-task plugin to manage javascript library dependencies.
Say I have installed jquery with bower:
bower install jquery --save
and with grunt-bower-task:
bower: {
install: {
options: {
targetDir: './public/lib',
layout: 'byComponent',
install: true,
verbose: true,
cleanTargetDir: true,
cleanBowerDir: false,
bowerOptions: {}
}
}
}
After running grunt bower, jquery will be copied to:
/public/lib/jquery/jquery.js
So the client will fetch jquery with url:
http://somedomain.com/public/lib/jquery/jquery.js
But I have question, what if I changed the jquery version?
Say I used another query version with bower, but it will still be copied to the same location and user will fetch it with the same url. If I have add cache-headers for it, user won't fetch new jquery.js code from server before expired.
How to fix this problem?
I think if we can add the version to the file name when running grunt bower, that will fix it, e.g.
http://somedomain.com/public/lib/jquery/jquery-1.8.js
But I can't find such functions in grunt-bower-task.
I would handle library versioning in the bower.json file. Yours should have the versions to be installed whenever you call the bower install command.. something like this
"dependencies": {
"angular": "~1.2.21",
"jquery": ">=2.1.1"
},
"resolutions": {
"jquery": ">=2.1.1"
}
But now they're all jquery.js regardless of the version. So now what you'd want to do is add some type of cache busting strategy which will force the browser to download the newest version of your scripts. There's tons of resource on cache busting javascript online, so I won't reiterate those here, but there are grunt tasks that can help you like this one
One slightly off topic suggestion I would make is to concat and minify your externals scripts into one js file and maybe another for your application scripts. As one or more of your external library change, the cache busting technique will force the browser to grab the latest version of your dependent scripts.
I currently am using a Yeoman seed project which comes with a Gruntfile and I'm having some trouble understanding parts of it. One particularly confusing thing is that during the development phase my SASS files are compiled into CSS and placed into a .tmp directory. My project however looks for main.css under app/styles yet the only thing there is my scss file. How is my project able to find main.css when it's not where it's looking?
./myApp
--Gruntfile.js
--.tmp
----main.css
--./app
----styles
------main.scss
When I create the dist folder the main.css file is placed correctly where it should be.
I think it may have to do with the compass or live-reload plugin.
I believe that you are talking about the situation when you ran grunt serve.
In the situation, the built-in server provides files under both .tmp and app directories by default which is specified for grunt-contrib-connect in Gruntfile like followings.
// The actual grunt server settings
connect: {
...
livereload: {
options: {
open: true,
base: [
'.tmp',
'<%= config.app %>'
]
}
},
This is why "styles/main.css" in index.html file goes to .tmp/styles/main.css.