After Vite production build modules are imported directly with hashes:
import someModule from "./someModule.e61757cb.js";
If I edit someModule — hash will be changed and hash of the module that import someModule also will be changed.
I have a big project with lots of modules. It's ineffective to load unchanged modules each time. I need to load only really changed modules.
I need to separate hashes into a chunk. I think it should be some 'require' facade like in Webpack. I can do it using Webpack, but it's too slow for my purposes.
How can I do it?
Related
I have browsed a lot of questions in this space, but I haven't found a clear answer.
I recently updated many of my project's npm dependencies to their latest. The project is entirely built around commonJS and most of the npm modules it includes use commonJS. However, a few (like chalk) now use ES syntax. Surprisingly I haven't found a reasonable way of including those modules.
Since I can apparently use import to load commonJS modules I guess I can change all the require statements to import, presumably having to use dynamic import for the few places where I'm using require dynamically. Is this the only solution? Seems silly to have to change the entire structure to support a few npm modules.
In the more recent versions of nodejs, the way to import an ESM module directly into a CommonJS module is with the dynamic version of import as in:
// import ESM module from CommonJS module
import("chalk").then(m => {
// use m here
});
This is the one way that import is allowed in a CommonJS module, though it may make coding and sticking with your CommonJS core a little more difficult.
This limitation is partially because ESM modules can use top-level await on asynchronous operations, but require() which CommonJS modules are built around is a purely synchronous model. So, allowing top level await in ESM modules is incompatible with a purely synchronous CommonJS loading architecture.
The dynamic import() is an asynchronous loading model so it can be used to load ESM modules, even in a CommonJS module.
With more and more NPM modules moving to ESM interfaces only, it appears that the writing is on the wall to begin transitioning projects over to ESM. ESM is fairly full featured and implemented now in both nodejs and browsers.
You can load CommonJS modules from ESM modules with the regular import so that makes it easier to move to ESM too.
Right now I'm going through my application, changing instances of this pattern:
import {Grid, Row, Col} from 'react-bootstrap'
into:
import {Grid, Row, Col} from '../react-bootstrap'
where react-bootstrap.js is a simple file at the root of my project, with a selective import of the ES6 modules I need from that NPM package:
import Grid from 'react-bootstrap/es/Grid'
import Col from 'react-bootstrap/es/Col'
import Row from 'react-bootstrap/es/Row'
export {Grid, Col, Row}
Doing this for a number of packages, I was able to reduce my bundle file size by more than 50%.
Is there a WebPack module or plugin that can do it automatically for any package?
If this transformation (that is, only including in the bundle what is explicitly imported, instead of the entire library) was applied recursively to the entire package tree, I bet we would see a dramatic size difference.
Edit: as Swivel points out, this is known as Tree Shaking and is supposed to be performed automatically by Webpack 3+ with UglifyJSPlugin, which is included in the production configuration from react-scripts that I'm using.
I'm not sure if this is a bug in either of those projects, but I'm seeing big size gains by doing selective imports manually, which shouldn't be the case if Tree Shaking was being performed.
I used to search for this and found this article. It is very helpful. I hope it works for you.
Whatever tool that would be would be equivalent to implementing tree shaking, and it would need to be integrated into your bundler. So, no.
For the record, dead code elimination is not the same thing as tree shaking. Tree shaking is breaking unused dependencies between modules. Dead code elimination is within a single module. Uglify.js only knows about one module at a time, so it cannot do tree shaking: it just does dead code elimination. So the fact that you are using the UglifyJSPlugin is irrelevant to whether or not your build environment has tree shaking.
I'm trying to figure out where dependency injection has it's place in Node. I can't seem to get my head around it even though I know how it works in Java and I've been reading countless blogs.
The examples on the net imo are to trivial. they don't really show Why DI is needed. I'd prefer a complicated example.
I've looked at the following frameworks:
https://github.com/young-steveo/bottlejs
http://inversify.io/
Now, Node uses the module pattern. When I do an import it receives a singleton since that's what node does, it caches modules, unless the factory pattern is used to return a new instance (return new MyThing()).
Now dependency injections primary function is to decouple everything.
When people say that, I get the notion that the goal is... To remove all the imports from the top of a module.
How I write today:
'use strict';
// node modules
import os from 'os';
...8 more modules here
import fs from 'fs';
// npm modules
import express from 'express';
...8 more modules here
import _ from 'lodash';
// local modules
import moduleOne from './moduleOne';
...8 more modules here
import moduleTen from './moduleTen';
//...rest of my code
Having 30 imports is a pain to change. Having the same 30 in multiple files is an even bigger pain.
I was reading https://blog.risingstack.com/fundamental-node-js-design-patterns/ and I looked at the dependency injection area. In the example 1 dependency is passed, fine. What about 30? I don't think that would be good practice?
How would one structure such an application with so many dependencies? And make it friendly for unit testing and mocking?
Implements an Ioc pattern as the dependency injection is in your projects always is a very good choice, this allows you to decouple and granulate your software making it more flexible and less rigid. with the node js module patter is very hard to implements abstraction in your code, that always is required in good architectures, also, doing it, make your code meets with the D [Dependency Inversion] from SOLID and make more easy implements the S-O-I.
If you wanna see an use case for DI, see the readme for this repository also a DI library for node Jems DI, it void the long importing list in modules, and do not make you depend 100% on it with things like putting metadata or forcing you to write extra code in your modules that depend on the DI libraries or sometimes are not needed for your business logic, always you put some abstraction between that DI library and your instances activation.
I have made a module for Node.js, which is part native, a C++ compiled library and half-JavaScript - about 10 *.js files. How should I distribute that? As single module or separately?
Depends on the use case I suppose, but as one module is probably fine. Unless you'd like to maintain them in separate repositories, you've got other modules that might prefer depending on them separately, or other otherwise and then it is just a matter of adding one to the other's package.json dependency list.
I have a Typescript project with plenty of circular dependencies. I am using requireJS for loading files on the browser. I am trying to refactor the project and I don't really know how to do it for optimal performance.
Here's the situation.
A.ts references B.ts and C.ts
B.ts references A.ts and C.ts
C.ts references A.ts and B.ts
I can either put reference tags in them and compile them with the --out option in the Typescript compiler into a single file. This make it hard to compile and debug so I am not inclined on this one.
I can use RequireJS to load them as independent modules.However, I am concerned because of the fact that there are so many circular dependencies - the browser will make too many requests for the same file. Secondly, I'm wondering if one one file request will cost considerbly lower bandwidth than multiple files of equal to to the sum of their sizes.
Please advise.
You will need to call require again to actually get the instance. See http://requirejs.org/docs/api.html#circular
RequireJS never requests the same file twice on the network so you should not worry about that.