Reputation: 3348
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
Reputation: 1837
You have two options: terser (javascript) or webpack (TypeScript).
It's better for javascript only.
How to:
npm install terser -g
or
yarn add terser
{
"compress": true,
"mangle": true,
"output": {
"file": "dist/your-minified-file.js"
}
}
{
(...),
"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
It is a bit more challenging to configure correctly, but it's better if you use TypeScript:
yarn add -D terser-webpack-plugin webpack webpack-cli webpack-node-externals
{
(...),
"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"
}
}
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