Uglified Javascript Throwing Errors - Only in Hubspot


#1

The Setup

We use webpack and the webpack uglifyJS plugin (https://github.com/webpack-contrib/uglifyjs-webpack-plugin/) on all of our projects to compile and minify our javascript. Using the default configuration - we’ve never run into issues with the compiled output.

In fact the same app.js file that we have compiled for this Hubspot project works fine on any webpage we throw it at, but when we try to load the JS file on Hubspot pages we get errors.

The Errors

Console errors such as Uncaught SyntaxError: Unexpected token * around license comments (again not an issue on other pages, only those running on Hubspot.

Attempted Fixes

We’ve tried adjusting the compilation output - but run into similar errors that can not be reproduced elsewhere. We’ve tested the Hubspot hosted pages logged in/out, incognito, etc.


403 Forbidden Error on Files (Codeship CD)
#2

Hi @dillonbailey,

Can you send me an example page/template in HubSpot where you’re seeing these issues? I’d like to investigate the issue directly.


#3

Hi @Derek_Gervais - we’ve actually fixed the issue by loading app.js via Files instead of Coded Files but I’d be happy to setup an example for you to see. If we load this exact same app.js file directly via Files it works A-ok.

https://inbound.honestfox.com.au/js-testing

The error is now Uncaught SyntaxError: Unexpected end of input because we tried a few different uglifyjs settings - but the result was similar.

Screenshot below of how the app.js is embedded.


#4

Dillon, have you tried uploading the unminified version to HubSpot? We automatically do the minification when a file is published.


#5

Hi @boulter we can give that a go sometime today and let you know the outcome.


#6

Hi Boulter,

Unfortunately it’s a no-go. We changed the settings to not compress the JS file and it still throws the error. Also - due to size restrictions we can’t upload the non-minified app.js (1.2MB) to coded files via FTP which is a requirement if we want to automate this process.

Exact same file referenced - only one error.

27 pm

Minification question

Also - when is the file minified? Because I’m getting this when previewing our JS file: https://inbound.honestfox.com.au/hubfs/app.js


#7

Thanks for trying that. Where is the 1MB limitation? You should be able to upload files > 1MB via FTP.

The file at https://app.hubspot.com/design-manager/3900783/code/5424939044 looks like it has already been minified. Were you able to upload or copy and paste in a unminified version?

Because minification can be slow, we don’t perform it immediately when you publish. It may take a few minutes or longer for the minified version to appear. We may also not minify at all if we encounter an error in the minification process.


#8

Looks like the upload error wasn’t size related but that Hubspot was unable to “validate the template” - is system/global reserved for *.html files?

I’ve tried reuploading and now get this strange issue where it turns the test.js or app.js files into basic templates? I’ll try copy and paste just to get a test running.


#9

Looks like the size limit is on direct entry into coded files via the GUI (screenshot attached) 1.5MB limit.
FTP of the non-minified file results in a few other issues, video here: https://youtu.be/o3heUc91yKg


#10

That’s strange that test.js ended up as a template. Are you confident that you uploaded a js file?

I noticed that FTP prevents you from uploading files > 1.5 MB in size. It’s possible that Transmit didn’t display the error, but you should see it in the Transcript under the Window menu.

We’ll look at what’s causing the minified files to be corrupted.


#11

Definitely a JS file - can send you the file if it would be helpful in debugging. Good to know the 1.5MB limit is via FTP or the GUI - so that’s just a general rule for coded files?

Thanks for taking a look - let me know if I can share our repo or anything that’s beneficial to creating the test.


#12

Hey @dillonbailey, realize I’m jumping in mid-way here, but in terms of that error you’re seeing in app.js when it’s included via Design Manager: it looks like the app.js file you’re working with: https://cdn2.hubspot.net/hubfs/3900783/app.js has a couple instances of {{index}} that you’re replacing in the initPagination() method. Since we render HubL in JS files in the Design Manager, that JS is breaking due to us interpreting that as a HubL variable call, so:
b.params.paginationBulletMessage.replace(/{{index}}/, t.index() + 1)
is rendering as:
b.params.paginationBulletMessage.replace(//, t.index() + 1)
which looks to be breaking the remainder of the file.

Wrapping your JS in {%raw%}{%endraw%} should prevent {{ from being interpreted as HubL.


#13

Jumping in mid-way with a cracking solution is well received!

Can the {% raw %} ... {% endraw %} go inside comments in the JS at the top and bottom of our bootstrap file? Or do they need to be outside comments?


#14

Hey Kevin,

So the {% raw %} tags helped solve one issue but created another - I’d like to roll this back to a single app.js file that should work in Hubspot, this will hopefully help us reach a solution, it may or may not need the {% raw %} tags but that’s something we can perhaps explore later.

The content from app.js has been pasted into this pen: https://codepen.io/dillonbailey/pen/BmpXrL

This file, when loaded through coded files which is preferred, creates a reproducible bug of unexpected token *

If you load this file into any other webpage, or even the codepen, you’ll see there’s no issues with how these comments are styled.

Looking forward to seeing what you think!


#15

Thanks for the example! I’ll take a look at this today.


#16

dillonbailey thank you very and very much for everything and for detailing showing everything. can i come back later asking for some questions as i see that you really know very well these things? now i cannot learn as i need to take hgh that my doctor prescribd to me and it impairs my thinking so i am not going to be able to learn now. thanks a lot.


#17

Any updates on your end mate?


#18

Hey @dillonbailey, thanks for your patience. I’ve been able to reproduce errors in our minification job for the source code here https://codepen.io/dillonbailey/pen/BmpXrL , but I haven’t been able to reproduce the apparent corruption of the minified version of the js file that’s causing the syntax error you mentioned above.

In other words, I can see where our minifier is tripping up, but in all of my tests the minification has failed and hasn’t generated a corrupted js file with the console errors you mentioned above. Do you have an example instance in your portal where you’re currently seeing the error? My test template, js file (copied from the pen), and page can be found here: https://inbound.honestfox.com.au/-temporary-slug-9cabf431-b706-4d43-af2a-3565d5a8a839?hs_preview=nvflSQSe-5434276548 .

For what it’s worth, the minifier doesn’t seem to like dot notation + reserved keywords, despite that being valid JS in modern ES. e.g. return t.default will cause an error, but return t['default'] will not. I’m filing an issue internally to see what we can do about that / what additional light we can shed on it.


403 Forbidden Error on Files (Codeship CD)
403 Forbidden Error on Files (Codeship CD)
#19

Hi @Kevin_Leonard thanks for raising this with the internal team!

I’ve done a new FTP with the exact same file config and it looks like when the raw tags are wrapped inside the file we are now error free!

I need to run the complete process with Codeship to validate that it’s all working as expected and include that raw string output in our build process with Gulp, but I would say we are very close!

Thanks again for your help.

DB


#20

I would say we are in business! Tested this deploying all the way through codeship and all systems are go! :rocket:

Basic Gulp task for incorporating into anyone else who has a similar workflow and needs this performed on their JS files to work with Hubspot due to {{ ... }} handlebars.

const gulp = require('gulp');
const path = require('path');
const inject = require('gulp-inject-string');
const notify = require('gulp-notify');

      gulp.task('wrapJs', function() {
        const paths = {
          dest: path.resolve(process.env.PWD, 'public/javascripts')
        }

        return gulp.src(paths.dest + '/app*.js')
          .pipe(inject.wrap('{% raw %}', '{% endraw %}'))
          .pipe(gulp.dest(paths.dest))
          .pipe(notify('JS wrapped'));
      });