digitalsparky / jekyll-minifier

Jekyll HTML/XML/CSS/JS Minifier utilising yui-compressor, and htmlcompressor
GNU General Public License v3.0
245 stars 25 forks source link

Problems with processed JS #14

Closed KarlBishop closed 6 years ago

KarlBishop commented 7 years ago

Hi, I switched my project to use processed JS (i.e. added a YAML FrontMatter block so I can use Liquid) and now the minifier doesn't seem to work.

I want to use Liquid so I can split my JS across multiple files then {% include %} it all at buildtime.

After the minifier runs on the processed JS, I'm seeing that line-breaks have been removed but comments and excess whitespace are still there (which breaks the script due to some single-line comments), and variable/function names are un-uglified.

Know any workarounds?

kenman345 commented 6 years ago

if you wrap it inside of <script>...</script> tags then it works but you'd have to use an include and cannot reference the js location in a <script src="..."> tag.

duhaime commented 5 years ago

@digitalsparky @kenman345 Can I follow up on this issue? It seems the processor is still not stripping frontmatter in included scripts.

Here's my setup:

.
├── Gemfile
├── Gemfile.lock
├── _config.yml
├── _layouts
│   └── default.html
├── _posts
│   └── 2019-02-21-hello
├── assets
│   ├── css
│   │   └── app.css
│   └── js
│       ├── 404.js
│       ├── app.js
│       └── main.js
└── index.html

Here's assets/js/app.js:

---
---
{% include_relative 404.js %}
{% include_relative main.js %}

Here's assets/js/main.js:

---
---
;(function() {
  console.log(site.main);
})();

Here's assets/js/404.js:

---
---
;(function() {
  console.log(site.four_oh_four);
})();

Inside of _config.yml I have:

jekyll-minifier:
  compress_css: true
  compress_javascript: true
  remove_comments: true

  uglifier_args:
    harmony: true

# vars
four_oh_four: 'four'
main: 'main'

Finally, here's _site/app.js:

---
---
;(function() {
  console.log(site.four_oh_four);
})();
---
---
;(function() {
  console.log(site.main);
})();

Do you know what I'm doing wrong? I'd like to get a minified js bundle that looks something like:

console.log(site.four_oh_four),console.log(site.main);

Is there a way to achieve this with this plugin? Any suggestions are welcome!

kenman345 commented 5 years ago

I'm not understanding the complete context but try not having frontmatter on the included scripts or moving the frontmatter included scripts to the include folder

duhaime commented 5 years ago

@kenman345 is there no way to have jekyll-minifier process js files after they've been processed into the _site directory?

I'm doing just this right now in another project by calling webpack in a simple plugin that triggers in the post_write event:

Jekyll::Hooks.register :site, :post_write do |jekyll|
  system('npm run compress')
end

I like the idea of using jekyll-minifier instead as it seems more minimal, but I'm still having trouble with the approach you mention. I have:

_includes/assets/js/404.js

---
---
;(function() {
  console.log(site.four_oh_four);
})();

_includes/assets/js/main.js

---
---
;(function() {
  console.log(site.main);
})();

assets/js/app.js

---
---

{% include assets/js/404.js %}
{% include assets/js/main.js %}

_layouts/default.html reads in this last file via:

<script src='{{ site.baseurl }}/assets/js/app.js' type='text/javascript'></script>

But the compiled _site/app.js still contains:

---
---
;(function() {
  console.log(site.four_oh_four);
})();
---
---
;(function() {
  console.log(site.duotone);
})();

Is there a way for me to make _site/app.js contain only a single line of comment-stripped, minified js? Any suggestions would be super helpful!

duhaime commented 5 years ago

In case others end up here looking for a super lightweight (as in, few plugins) way to combine js and css files, I'll post what I ended up doing below.

The simplest approach to this task in my opinion is to just combine js into one file, combine the css into one file, and inline both on the raw page. This can greatly reduce the number of network requests required to load your page. (This is what google.com does.)

To accomplish this, one can place all css and js assets into _includes directory

Duhaime:_includes doug$ tree .
.
└── assets
    ├── css
    │   ├── reset.css
    │   └── app.css
    └── js
        ├── 404.js
        └── app.js

Then _includes/assets/css/app.css can include all of the css files:

{% include assets/css/reset.css %}

Likewise, _includes/assets/js/app.js can include all the js files:

{% include assets/js/404.js %}

Then one can inline those onto a page with the following tags:

<!DOCTYPE html>
<html lang='en'>
  <head>
    <!-- CSS is inlined below -->
    {% capture styles %}{% include assets/css/app.css %}{% endcapture %}
    <style>{{ styles | scssify }}</style>
  </head>
  <body>
    <div id='content'>
      {{ content }}
    </div>
  <!-- JS is inlined below -->
  <script>{% include assets/js/app.js %}</script>
  </body>
</html>

Then to minify everything, we can add to Gemfile:

gem 'octopress-minify-html'

Finally we update the _config.yml and add the following:

minify_html: true

sass:
  style: compressed

plugins:
  - octopress-minify-html

Then on rerender, the output pages will contain the combined and minified css and js assets without incurring additional network requests.