Meek
Meek

Reputation: 3348

Npm scripts - how to minify files from a folder and save them into another?

I'm using npm scripts to compile and minify sass and potentionally javascript files. However, I'm looking for at way to specify a source folder of *.js files and have them minified and saved in a destination folder individually - (flattened, not concatenated) each as *.min.js.

I have tried with npm terser, but it doesn't seem to be able to with with a source folder, only single files, nor does it seem to be able to minify the files individually.

So, what I'm looking for:

Src/
 |__main.js
 |__menu.js
 |__etc...
Dist/
 |__main.min.js
 |__menu.min.js
 |__...

Which npm package should I use for this?

Upvotes: 0

Views: 1287

Answers (2)

Daniel Santana
Daniel Santana

Reputation: 1837

You have two options: terser (javascript) or webpack (TypeScript).

Terser

It's better for javascript only.

How to:

  1. Install
  npm install terser -g

  or

  yarn add terser

  1. Create your terser.config.json (in your root folder)
  {
  "compress": true,
  "mangle": true,
  "output": {
    "file": "dist/your-minified-file.js"
  }
}
  1. package.json script:
{
  (...),
  "scripts": {
    "minify": "terser src/input-file.js -c terser.config.json",
  },
  "devDependencies": {
    "terser": "^5.31.0"
  }
}

Or, if you want to skip the config file, you need to add the options to your script line. Example: terser src/input-file.js -o dist/minified-file.js.

More info can be found in the terser page or Terser GitHub

Webpack

It is a bit more challenging to configure correctly, but it's better if you use TypeScript:

  1. install
  yarn add -D terser-webpack-plugin webpack webpack-cli webpack-node-externals

  1. Package.json
{
  (...),
  "scripts": {
    "minify": "SERVER_ENV=dev webpack --config webpack.config.mjs",
  },
  "devDependencies": {
    "terser-webpack-plugin": "^5.3.10",
    "webpack": "^5.91.0",
    "webpack-cli": "^5.1.4",
    "webpack-node-externals": "^3.0.0"
  }
}

3) webpack.config.js

Webpack configuration is more complex and vast. I recommend reading this StackOverflow Answer to better understand the meaning of webpack.DefinePlugin.

import { resolve, dirname } from 'path';
import { fileURLToPath } from 'url';
import nodeExternals from 'webpack-node-externals';
import NodePolyfillPlugin from 'node-polyfill-webpack-plugin';
import TerserPlugin from 'terser-webpack-plugin';
import webpack from 'webpack';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const isProd = process.env.SERVER_ENV === 'prod'
const mode = isProd ? 'production' : 'development';

export default {
  entry: './src/index.ts', // your starting index
  output: {
    path: resolve('dist'),
    filename: 'index.min.js' // your output & folder
  },
  mode,
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: 'ts-loader',
        exclude: /node_modules/
      }
    ]
  },
  target: 'node',
  externals: [nodeExternals()],
  resolve: {
    extensions: ['.ts', '.js'],
    alias: {
      'apis': resolve(__dirname, 'src/apis'), // this allows you to import your scripts using an alias, for example, `import { someApi } from 'apis';`
    }
  },
  optimization: {
    minimize: isProd, // minimization true or false
    minimizer: [new TerserPlugin({
      extractComments: false,
      terserOptions: {
        ecma: 2017,
        output: {
          comments: false
        },
        mangle: {
          toplevel: true
        }
      }
    })]
  },
  plugins: [
    new NodePolyfillPlugin(),
    new webpack.DefinePlugin({
      'process.env': 'process.env', // this is important. You can either pass the env file, a set of properties or 'process.env' to make your script configuration loading more dynamic (check the link below)
    })
  ],
};

Finding this 'process.env': 'process.env', setting was challenging, so I wrote a blog post about it. You can find it here, but I recommend the official documentation (it is not very clear on this topic) to get more info about the webpack possibilities. The official documentation can be found here.

Upvotes: 2

Meek
Meek

Reputation: 3348

So, it seems that the package Terser folder can do just this...

Upvotes: 0

Related Questions