How can Modernizr 3.x modules be required? - modernizr

I am trying to require specific Modernizr tests into a browserify project but i must be doing something wrong.
I use the deamdify transform when building using browserify.
Modernizr is required as an NPM package directly from the source repo's master. The reason this happens is because pending v3.x will be available through npm and the latest bower packages do not offer the sources, only prebuilt versions.
I want to be flexible with what Modernizr modules i include in my application so for my needs, having an extra build-modernizr step is not acceptable. I want to have a single build step, browserify.
The problem is that deamdify fails to recognize the required Moderizr modules as AMD and does not resolve their dependencies or wrap them in AMD containers...
I have setup a repo that illustrates the problem:
https://github.com/thanpolas/browserify-modernizr

Nope, you aren't doing anything wrong. Its just not set up to work like that quite yet. Its a bit of a custom AMD.
#robw has been working on a new build system that I believe would show you to do what you are looking for.
update: the new build system is finally in effect - using master as of 2/8/2015 you can require tests

Though you said that having an extra build-modernizr step is not acceptable for you (I provided answer for that case) but still I want to add another answer for the case when using browserify and Modernizr with gulp.
gulp-modernizr can crawl through specified files, find Modernizr usages and make custom Modernizr build:
npm install --save-dev gulp-modernizr
Define gulp task in gulpfile.js:
var modernizr = require('gulp-modernizr')
gulp.task('modernizr', function () {
return gulp.src('src/**/*.js')
.pipe(modernizr())
.pipe(gulp.dest('build'));
});
This task generates build/modernizr.js that contains only tests used in your source code. When added to html file with <script> tag this file sets Modernizr instance to window.Modernizr property. So you can use it like:
if (window.Modernizr.filereader) {
// your code here
}
Using modernizr as module.
If you want to use modernizr as module (see this issue for discussion) than create src/modernizr.js file:
module.exports = window.Modernizr;
And expose this file as module with name modernizr:
var browserify = require('browserify');
var source = require('vinyl-source-stream');
gulp.task('browserify', ['modernizr'], function() {
var b = browserify({ entries: 'src/index.js' });
b.require('src/modernizr.js', {expose: 'modernizr'});
return b.bundle()
.pipe(source('index.js'))
.pipe(gulp.dest('build'));
});
Now you can use it in your source code:
var modernizr = require('modernizr');
if (modernizr.filereader) {
...
}
Injecting build/modernizr.js and build/index.js scripts in index.html.
Suppose you have src/index.html:
<!DOCTYPE html>
<html class='no-js' lang=''>
<head>
<meta charset='UTF-8'>
<title>Example</title>
<!-- inject:head:js -->
<!-- endinject -->
</head>
<body>
<!-- inject:js -->
<!-- endinject -->
</body>
</html>
The following gulp task will inject build/modernizr.js in head section and build/index.js in body section and place resulting file to build/index.html:
var inject = require('gulp-inject');
gulp.task('html', ['browserify'], function() {
return gulp.src('src/index.html')
.pipe(inject(gulp.src('build/modernizr.js', { read: false }),
{ ignorePath: 'build', addRootSlash: true, starttag: '<!-- inject:head:{{ext}} -->'}))
.pipe(inject(gulp.src('build/index.js', { read: false }),
{ ignorePath: 'build', addRootSlash: true}))
.pipe(gulp.dest('build'));
});

With browsernizr you can specify what tests you need in your source code.
Install:
npm install --save browsernizr
Use:
// pick what tests you need
require('browsernizr/test/css/rgba');
require('browsernizr/test/file/filesystem');
require('browsernizr/test/websockets');
// make sure to do this after importing the tests
require('browsernizr');
// or if you need access to the modernizr instance:
var Modernizr = require('browsernizr');
browserify will include required tests in bundle.

Related

vitePreprocess in SvelteKit triggers Preprocessor dependency "sass" not found when using scss

I have a brand new project using SvelteKit. By default, vitePreprocess is used to handle scss and other files, as described in the docs:
vite-plugin-svelte offers a vitePreprocess feature which utilizes Vite
for preprocessing. It is capable of handling the language flavors Vite
handles: TypeScript, PostCSS, SCSS, Less, Stylus, and SugarSS. For
convenience, it is re-exported from the #sveltejs/kit/vite package. If
you set your project up with TypeScript it will be included by
default:
// svelte.config.js
import { vitePreprocess } from '#sveltejs/kit/vite';
export default {
preprocess: [vitePreprocess()]
};
However, if I use lang="scss" in my files:
<style lang="scss">
....
</style>
I get the following error:
Error: Error while preprocessing /Users/francesco.leardini/Documents/pet projects/budget-tracker/src/routes/+page.svelte - Preprocessor dependency "sass" not found. Did you install it?
at loadPreprocessor (file:///Users/francesco.leardini/Documents/pet%20projects/budget-tracker/node_modules/vite/dist/node/chunks/dep-5e7f419b.js:36922:19)
at scss (file:///Users/francesco.leardini/Documents/pet%20projects/budget-tracker/node_modules/vite/dist/node/chunks/dep-5e7f419b.js:36962:20)
at compileCSS (file:///Users/francesco.leardini/Documents/pet%20projects/budget-tracker/node_modules/vite/dist/node/chunks/dep-5e7f419b.js:36482:40)
at async preprocessCSS (file:///Users/francesco.leardini/Documents/pet%20projects/budget-tracker/node_modules/vite/dist/node/chunks/dep-5e7f419b.js:36644:12)
at async style (file:///Users/francesco.leardini/Documents/pet%20projects/budget-tracker/node_modules/#sveltejs/vite-plugin-svelte/dist/index.js:2055:20)
at async process_single_tag (file:///Users/francesco.leardini/Documents/pet%20projects/budget-tracker/node_modules/svelte/compiler.mjs:46844:27)
at async Promise.all (index 0)
at async replace_in_code (file:///Users/francesco.leardini/Documents/pet%20projects/budget-tracker/node_modules/svelte/compiler.mjs:46732:26)
at async process_tag (file:///Users/francesco.leardini/Documents/pet%20projects/budget-tracker/node_modules/svelte/compiler.mjs:46858:29)
at async preprocess (file:///Users/francesco.leardini/Documents/pet%20projects/budget-tracker/node_modules/svelte/compiler.mjs:46898:30)
Shouldn't scss files be handled out of the box as stated in the docs?
Add the dependency sass to your project first?
npm add -D sass or with whatever package manager you use.

Cache transformed node modules with vite/esbuild

vite build uses esbuild to transform both the package dependencies (node modules) as well as the app source code into the target JavaScript specification, i.e. es2015.
I observe that vite/esbuild re-transform the entire sources in ./node_modules every time vite build is run.
How can this build stack be used to keep and reuse the previously transformed files, at least for the entire ./node_modules folder (given dependencies didn't change of course) so that subsequent vite build command invocations run significantly faster?
One way to improve the performance of subsequent Vite build command invocations is by using a caching mechanism. You can use a caching tool such as cache-loader or hard-source-webpack-plugin to cache the transpilation results of the node modules.
This will allow Vite to reuse the previously transpiled files for the node modules, as long as the dependencies haven't changed.
This can greatly speed up the build process.
You can also try to configure esbuild to only transpile the changed files instead of the entire codebase using the -w or --watch option when running the esbuild command. This option tells esbuild to watch the input files and only transpile the files that have been modified.
In Vite, you can configure the esbuild plugin to use the --watch option by adding the following to your vite.config.js file:
const esbuildConfig = {
watch: true,
};
module.exports = {
esbuild: esbuildConfig,
};
Examples :
cache-loader:
Install the package:
npm install cache-loader --save-dev
In your vite.config.js file, configure the cache-loader to be used for transpiling the node modules by adding it as a rule in the build object:
module.exports = {
build: {
...
css: {
...
},
js: {
...
loaderOptions: {
cache: true,
cacheDirectory: 'node_modules/.cache'
}
},
...
}
}
Run your build command ( vite build )
hard-source-webpack-plugin:
install the package:
npm install hard-source-webpack-plugin --save-dev
In your vite.config.js file, import the plugin and add it to the build.plugins array:
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
module.exports = {
build: {
...
plugins: [
new HardSourceWebpackPlugin()
],
...
}
}
Run your build command (vite build)
These examples, as you asked in your comment, are for Vite versions 2.5.8 and 3.x. However, in order to use them with Vite 3.x you need to update the build config to match the new format.
Please don't hesitate to write a comment if you still have a problem or questions!

How to serve frontend using frontend maven plugin in gradle based project?

I have read some online blogs that states adding this plugin builds Angular frontend so it would be easier to serve angular content from a spring boot path - resources/static folder. But couldn't find any example for gradle projects.
I have a gradle project which consists of modules for backend and frontend and trying to host it on same server port. I added :
compile group: 'com.github.eirslett', name: 'frontend-maven-plugin', version: '1.6'
Then ran ng build in frontend dir to build ng components. I see some.js files and following index.html generated :
<html lang="en">
<head>
<meta charset="utf-8">
<title>Welcome App</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
<script type="text/javascript" src="runtime.js"></script><script type="text/javascript" src="polyfills.js"></script><script type="text/javascript" src="styles.js"></script><script type="text/javascript" src="vendor.js"></script><script type="text/javascript" src="main.js"></script></body>
</html>
From my understanding adding above dependency just take care of install npm and node dependencies but won't build ng components. So I manually ran ng build and the those files gets generated in resources/static directory(as I changed outputPath in angular.json). But unable to serve them from tomcat startup.
I just have 3 ng components where the main login component uri should be accessible at "/" and routing works fine and handled by angular(ng serve shows UI pages) but just not when in spring-boot path so as to deploy on same server port as backend.
imports: [
BrowserModule,
HttpModule,
FormsModule,
RouterModule.forRoot([
{
// empty path is the default page for app; redirects to Login component
path: '',
component: LgnComponent
},
{
path: 'test',
component: TestComponent
},
{
path: 'sale',
component: SaleComponent
}
])
My only problem is http://localhost:8080/ displays no UI(login etc.)
I mean to ask are there any additional steps beyond adding this
dependency to build.gradle in order to easily serve them?
I guess I don't know what URI to use to access frontend on 8080. Because angular routing works fine and was able to access on localhost:4200/ and from the main login page to localhost:4200/test and /sale .
Please help, I have been struggling/banging my head on this issue for sometime now.
Building your frontend application in Gradle with the frontend-maven-plugin is not relevant, because this plugin is designed for Maven, not Gradle. You may take a look at the Siouan Frontend Gradle plugin, that will allow you to trigger your frontend application build directly from Gradle. From the official website:
It is inspired by the frontend-maven-plugin.
This other answer to a similar question provides an example of how to use this plugin. Here's a minimal configuration example to build your frontend application:
// build.gradle
plugins {
id 'org.siouan.frontend' version '1.1.2'
}
frontend {
// Replace with your Node version.
nodeVersion = '10.15.3'
// Replace 'build' by the name of your script in your project's 'package.json' file.
assembleScript = 'run build'
}
Having your freshly built frontend application served by your Spring Boot backend and correctly packaged in your final archive are different problems. You'll find a working example of a Angular + Spring Boot + Gradle application by generating a demo application with JHipster and its JHipster Online service. This will also show you where the different artifacts are generated to be served either by the backend or the frontend development server.
EDIT
The plugin's homepage now provides some usage guidelines, that may help 'packaging' a frontend and a Java backend together.
The plugin seems a bit outdated.
I am using the gradle node plugin. You add the build command to package.json and then execute the script via the plugin:
package.json:
{
"name": "stuff",
"version": "0.1.4",
"license": "MIT",
"scripts": {
"buildProd": "ng build -prod"
}
...
}
build.gradle:
//execute buildProd script from project.json
task buildClient(type: NpmTask, dependsOn: [npmInstall]) {
args = ['run-script', 'buildProd']
}
task copyClient(type: Copy, dependsOn: [buildClient]) {
from 'dist'
into "${buildDir}/resources/main/static"
}
//build & copy client before processResources
processResources.dependsOn copyClient

gulp, wiredep and custom sass file

So I made a library that I can bower install using a direct link. I can use this library from another internal application by adding the library name in the dependency of the bower.json file. When other internal application does a bower update, the changes I made on the library will be applied to their application. This part is working very well.
Now, I'd like the other software devs to have freedom to change the styles. They can create css file directly and that will work. However, it's a hackish route. I can provide them the same settings file that I use.
So i tried putting that file in the main section of the bower.json but wiredep is processing it. I put it in exclude and the error is gone when I run gulp.
"main": [
"dist/stylesheet.css",
"src/_settings.scss"
],
this is the code that prevented it from being parsed by wiredep
wiredep: {
directory: 'bower_components',
exclude: ['css/foundation.css','src/_settings.scss']
}
Am I right that I'll have to create a new gulp task and put 'src/_settings.scss' as gulp.src like this
gulp.task('sasstask2', function () {
return gulp.src('src/_settings.scss')
.pipe($.sass())
.pipe(gulp.dest('src/css'));
});
I also like the generate css to be injected to index.html but not sure how to do it? Will wiredep automatically inject it to index.html?

Angular generator without Ruby

The angular generator has a dependency on compass and thus ruby when using SASS.
Two questions:
Is it possible/practical to remove the ruby dependency by using something like node-sass?
If so, how do I accomplish #1 and still use angular generator to generate controllers, routes, services, etc in the future?
If you are using the Yeoman Angular generator and you wish to use SASS/SCSS without depending on Ruby, you could use the grunt-sass Grunt module.
Yeoman is essentially a project set-up with Grunt so you can just add whichever Grunt modules you need. If you are unfamiliar with Grunt, you can read the documentation here.
Essentially, you can set up the Grunt configuration for your SASS task, then register the task in your generated project's Gruntfile.js:
grunt.initConfig({
sass: {
options: {
sourceMap: true
},
dist: {
files: {
'main.css': 'main.scss'
}
}
}
});
grunt.registerTask('default', ['sass']);
You should note that this Grunt module uses Node SASS for CSS compilation instead of Compass, so you may be missing out on some Compass mixins you may be used to.

Resources