Closed surjithctly closed 4 years ago
Wondering if you could just create src/js/main.js.njk (or liquid or whatever template you want), wrap the whole template it in some custom {% jsmin %}...{% endjsmin %}
Terser paired tags, and then set a custom permalink
to "/js/main.min.js" in your frontmatter.
Possibly not ideal as you'd probably lose the ability to lint your JavaScript via ESLint in the process though. Not sure if it'd be better to do minification via a separate post-Eleventy-build hook in your package.json file's "scritps":
"build": "eleventy build",
"postbuild": "npm run minify:js",
"minify:js": "terser src/js/main.js --compress --mangle -o _site/js/main.min.js",
"start": "....",
"test": "...."
Hello @pdehaan
Writing JS inside njk doesn’t seems a good idea. I was thinking Eleventy provides some option for this like Gulp.
The second option seems a good idea, but how can we make sure it always run together? In your example, I think I needed to run both command separately.
Still wondering how do others do it..
Npm scripts with “pre” and “post” prefixes are a bit special. https://www.yld.io/blog/using-npm-pre-and-post-hooks
So if you type npm run build, it would automatically running any prebuild
, build
, then postbuild
script. So you’d only need to type one command, but it wouldnt run postbuild
if you typed eleventy
directly from your Terminal.
Sorry, me again... OK I think I found a solution. By putting the JavaScript file in /src/_includes/, and then including the file elsewhere and wrapping it in a {% terser %}...{% endterser %}
shortcode, I think I got your use case working (without the need for extra build steps).
https://github.com/pdehaan/11ty-terser-test
tree . -aI "node_modules|.git"
.
├── .eleventy.js
├── .gitignore
├── package-lock.json
├── package.json
│
├── src # <<<<< INPUT FOLDER
│ ├── _includes
│ │ ├── layouts
│ │ │ └── base.njk
│ │ └── site.js
│ ├── index.njk
│ └── scripts.njk
│
└── www # <<<<< OUTPUT FOLDER
├── index.html
└── site.min.js
4 directories, 10 files
So, src/_includes/site.js contains some truly horrible JavaScript.
In src/scripts.njk we set our output file permalink (so it writes a JavaScript file), and include our site.js file from src/_includes/, and wrap all the included output in our {% terser %}...{% endterser %}
paired shortcode:
---
permalink: /site.min.js
---
{% terser %}
{%- include "site.js" -%}
{% endterser %}
This should let you still keep your JavaScript in a .js file so it can easily be formatted by Prettier or linted by ESLint, and your minified file gets written out to a separate file instead of inlined.
And if we open www/site.min.js in our code editor, we can see that it is beautifully minified.
function hello(l){l||(l="World"),alert("Hello "+l)}
Finally, my terser
paired shortcode is just the same example I posted over in https://github.com/11ty/eleventy/issues/1344#issuecomment-676497888 since I couldn't remember how to do the async terser in a sync paired shortcode off the top of my head.
const makeSynchronous = require("make-synchronous");
const jsmin = makeSynchronous(async (code="", opts={}) => {
const Terser = require("terser");
try {
const minified = await Terser.minify(code, opts);
return minified.code;
} catch (err) {
console.error(err);
// Unexpected minify error. Return unminified code.
return code;
}
});
module.exports = function (eleventyConfig) {
eleventyConfig.addPairedShortcode("terser", jsmin);
return {
dir: {
input: "src",
output: "www"
}
};
};
Thanks a lot. Let me try it.
Actually, another (probably better) approach is to use Eleventy transforms.
Example repo at https://github.com/pdehaan/11ty-transform-async (does both HTML prettification/minification and JavaScript minification).
Oh Cool...
However don’t you think there should be a simple way in eleventy to handle this? Something similar to Gulp?
I think #117 would make this easier, so feel free to upvote that for a better workflow.
I don't know that adding a bunch of extra complexity to make Eleventy behave like Gulp is the best solution. Pretty sure you can use Gulp+Eleventy together now if you want. I've seen several 11ty templates out there that have full build systems like webpack or parcel or babel which do all sorts of clever file processing and that seems to work fairly well if you need a more robust solution.
I thought that because I was using Gulp (because I couldn't figure out how to set up my build using eleventy.js) that I was in a way, doing it wrong. Or that using eleventy.js was the better way to do it. It's confusing that there aren't "standard" ways of doing this without reverting to Grunt or Gulp. But I am very thankful that 11ty can work easily with other build tools.
@surjithctly I laughed at your comment because that was one of the most surprising things about 11ty. Even after looking at many starter projects I had to fall back to Gulp because it was familiar.
I thought that because I was using Gulp (because I couldn't figure out how to set up my build using eleventy.js) that I was in a way, doing it wrong.
I dont think there is anything wrong with using Gulp+Eleventy together. I've seen quite a few starter projects that use both, or integrate with other tools like Tailwind. In fact, https://piccalil.li/course/learn-eleventy-from-scratch/ has a great section (See Module 2: Asset Pipeline) on using Gulp for processing Sass (via gulp-clean-css, and gulp-sass), fonts (via get-google-fonts), and images (via gulp-imagemin) w/ Eleventy. Highly recommend checking the course out.
Hello,
I have seen Eleventy uses "Terser" plugin for minification. However the docs only explain how to inline it.
Suppose I have a file
js/main.js
then I want to minify it using Terser asjs/main.min.js
and then runaddPassthroughCopy
to copy to_site
.src/js/main.js --> src/js/main.min.js --> _site/js/main.min.js
is it something possible with Eleventy? if yes, Can share the sample code?
Thanks a lot.