Home > database >  Import node_modules to local files instead of importing from node_modules after build?
Import node_modules to local files instead of importing from node_modules after build?

Time:01-23

I am currently using tsup and/or unbuild to bundle my own small library. I want to be able to import a third-party library, say change-case, and use the code. Whenever I build the project, is it possible for the bundler to add the code directly to my output file instead of it importing it from node_modules, which should make my bundle-size smaller, not being dependent on third party code? Is that possible?

This is what I mean:

input file

import {camelCase} from "change-case"

const someFunction = (value: string) => camelCase(value)

How output currently looks after build

import {camelCase} from "change-case"

const someFunction = (value: string) => camelCase(value)

How I want it to look after build

const camelCase = (value: string) => {
    // whatever logic resides within the module
}

const someFunction = (value: string) => camelCase(value)

Meaning the end-user does not have to install change-case to their node_modules, they will only get the necessary parts from that library?

CodePudding user response:

Intro

As I understood your question is about how to bundle a third-party library with a project, in order to reduce the size of the bundle and remove dependencies on external code. The goal is to include only the necessary parts of the library in the final output file, rather than the entire library.

Tree Shaking

One way to achieve this is to use a technique called "tree shaking" which is supported by bundling tools such as webpack or rollup. Tree shaking allows you to only include the parts of a library that are actually used in your project.

Tools webpack: With webpack, you can use the babel-plugin-lodash to import only specific methods from a library, rather than the entire library. This can help to reduce your bundle size. Additionally, you can use terser-webpack-plugin which minifies the output file, and will remove any dead code (unused code) from the final output file, this can also help in reducing bundle size.

tsup and/or unbuild: I couldn't find much information about the mentioned tools, but you can check the documentation if they provide similar options.

Code example:

Here is an example of how you can use webpack to bundle a third-party library, change-case, and include only the parts of the library that are actually used in your project.

In this example, I am using the babel-plugin-lodash to import only the camelCase method from the change-case library, rather than the entire library.

// webpack.config.js
const webpack = require('webpack');
const { TerserPlugin } = require('terser-webpack-plugin');

module.exports = {
  // other webpack configs
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          output: {
            comments: false,
          },
        },
      }),
    ],
  },
  plugins: [
    new webpack.LoaderOptionsPlugin({
      options: {
        babel: {
          plugins: ['lodash'],
        },
      },
    }),
  ],
};


// index.js
import { camelCase } from 'change-case';

function someFunction(value) {
  return camelCase(value);
}

In this example, webpack will bundle only the camelCase method from change-case library, and remove any dead code from the final output file, this can make your bundle smaller and remove the dependency of the third-party library.

Please note that this example is just an illustration, it might not work as is and require some modifications to match your project's configuration.

Conclusion

In conclusion, it is possible to bundle third-party libraries directly into your output file using webpack, rollup or other similar tools and options. By using tree shaking and minification techniques, you can reduce the size of your bundle and remove any unnecessary code.

CodePudding user response:

You can set how imports are resolved in your builder config. The tag says you use rollup, where it is set by the inlineDynamicImports property:

// in rollup.config.mjs
const config = defineConfig({
  plugins: [...],
  input: {...},
  output: {
    ...
    inlineDynamicImports: true,
    format: 'iife',
  },
});

Note that inlineDynamicImports does not work with all format types.

  • Related