Cache transformed node modules with vite/esbuild - caching

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!

Related

How can I package symbolic link in node_modules with `serverless?

I am using serverless to package nodejs application. I am using yarn workspace in my project.
- common
- projectA
- projectB
the projectA and projectB are using common module which is managed by yarn workspace. It creates a link inside node_modules/common -> ../common. But when I package the application with sls deploy, it doesn't inlude the link node_modules/common. How can I make it package symbolic link?
You should start using code bundler.
What is code bundler?
What code bundler does:
It scans your AWS Lambda code structure through all of the files, starting from handler file.
It goes through all of the imports to create a tree of dependencies.
Then it inlines all of those dependencies into single "fat" file.
After that you are free to deploy your application, which has only single file.
As you can see, it's a perfect match for AWS Lambda and your use case.
All of the dependencies from common package will be included in the output file.
Also code bundlers have other cool features, like removing all of the unneeded files, that are defined in libraries that you use, but you are not using them directly. Due to this output package size of your Lambda will be a lot smaller, which will decrease cold starts.
How to achieve that using Serveless Framework
The easiest way is to start with serverless-webpack plugin, which includes Webpack (one of the most popular code bundlers) and some most common configurations for it.
After adding this plugin, simply configure it in serverless.yml:
custom:
webpack:
webpackConfig: 'webpack.config.js' # you can remove it, it's the same as default
packager: 'yarn'
Now you need to configure Webpack using webpack.config.js file. There are a lot of possibilities to configure it and the example below is the most basic one:
const path = require('path');
const slsw = require('serverless-webpack');
module.exports = {
entry: slsw.lib.entries,
target: 'node',
mode: slsw.lib.webpack.isLocal ? 'development' : 'production',
stats: 'minimal',
devtool: 'nosources-source-map',
externals: [{'aws-sdk': 'commonjs aws-sdk'}],
resolve: {
extensions: ['.js', '.json'],
},
output: {
libraryTarget: 'commonjs2',
path: path.join(__dirname, '.webpack'),
filename: '[name].js',
sourceMapFilename: '[file].map',
},
};
Now when you call sls package in projectA or projectB, then after unzipping ./.serverless/functionName.zip, you will find just single "fat" file, that will include all of the required dependencies.
During sls deploy phase, this file will be deployed as Lambda handler.
Correctly defining dependencies
Make sure, that common package is listed as dependency of projectA and projectB:
// common/package.json
{
"name": "#your-project/common",
"version": "1.0.0",
"license": "ISC",
}
// projectA/package.json
{
"name": "#your-project/packageA",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"#your-project/common": "1.0.0"
}
}
Thanks to this, you will be able to reference commons in pakcageA imports via:
import exampleHelper from '#your-project/common/src/exampleHelper';
Project using this approach can be found on my Github here:
https://github.com/PatrykMilewski/serverless-series

How to automatically add a module rule to react-scripts' webpack.config.js when using "npm install"

I've built my application with create-react-app, and to make it work I have to add
{
test: /node_modules.+js$/,
loader: require.resolve("ify-loader"),
},
to the module.rules array of react-scripts' webpack.config.js file.
What I should I do to make it add automatically when creating the node_modules folder with the command npm install?

Are there ways to perform postCSS processing withouth gulp or grunt. Only with help of maven?

I want to perform postprocessing in my project with help of postCSS.
As I'm new in frontend I read only ways to perform it by frontend build system (grunt or gulp).
But maybe the ways to postpocess only with maven?
You can use postcss-cli to run it through the command line.
The command usage is pretty straight-forward.
postcss [options] [-o output-file|-d output-directory] [input-file]
Also, if you are using npm along with a package.json file, I would advise you to add a run-script:
{
"name": "my-app",
"script": {
"css": "postcss your options -go here"
},
"dependencies": {
"postcss":"^4.1.13"
}
}
So you can simply run npm run css from maven / CLI without having to worry about prefixing your command node_modules/bin and having your options in maven.

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?

Difference between Grunt SASS task properties options, dist and dev?

As I am editing the sass task of my Gruntfile.js I don't understand the difference between the different properties (e.g. dist, dev and options) of the sass task object.
For example, in the code below the sass object contains two properties, options and dist. I have also seen a dev property in some other examples of the sass task.
sass: {
options: {
includePaths: ['bower_components/foundation/scss']
},
dist: {
options: {
outputStyle: 'compressed'
},
files: {
'css/app.css': 'scss/app.scss',
// our component file on the right
// file to save on the left
'css/top-bar.css' : 'scss/topbar.scss'
}
}
},
At the grunt-sass Github documentation only the options property is discussed. There is no mention of dist and dev but I see that options can appear in dist and dev. Logic tells me that dist is for the final build and that dev is for development. I'm not sure though and also not sure how to use them. Any ideas?
When configuring a task, you can have many targets, like dist or dev (you can name them whatever you want). Each target can have its own settings, which obviously depends on the task.
I'm not sure which task you're using (maybe grunt-sass?), but the outermost options is probably applied to all targets.
See this part of Grunt's documentation.

Resources