question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Install via npm and `import`?

See original GitHub issue

I’ve just tried to import htmx into our build (webpack), and while it builds fine, in the browser I get the following JS error:

Uncaught TypeError: Cannot read property 'logger' of undefined

It’s entirely possible that the JS is being mangled by webpack, perhaps the minification routine, but I’m not importing it any differently than any other package (flickity, alpine, etc).

Any tips would be appreciated!

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:21 (17 by maintainers)

github_iconTop GitHub Comments

7reactions
1cgcommented, May 30, 2020

it’s almost like i hate javascript and I’m writing all this javascript to avoid writing javascript

2reactions
GavinRay97commented, May 30, 2020

Okay, I got it working.

So what I did was:

  1. Took all of the IIFE stuff that was defined in some of the extensions (wrapping them in (function () { })()) out first

  2. Removed the AMD stuff from the main htmx.js and put it back to the way it was initially written:

var htmx = htmx || (function () {
        'use strict';

So now in the top of the bundle there’s an IIFE that defines htmx.

This library is written in a bit of an usual style, without using imports/exports. So there’s a sort of “stateful” dependence with these modules.

The easiest way to get around this is to deterministically load the contents of the entrypoint/main bundle first, so that in the order of execution the var htmx = IIFE is always loaded before any other code from extensions etc. can reference it.

I used a small gulpfile to concatenate the contents of htmx.js and all of the extension code into a single bundle:

// gulpfile.js
const { src, dest } = require('gulp')
const concat = require('gulp-concat')

// This always reaches `htmx.js` first since it's in a closer directory
// But probably better to explicitly pipe `htmx.js` and then all others
exports.default = function () {
  return src('src/**/*.js')
	.pipe(concat('htmx-bundle.js'))
	.pipe(dest('output/'))
}

This spits out a single-file bundle that works perfectly in browser containing all extension code. (This may or may not be desirable, I just wanted to test extension functionality too so this was easiest).

Then the last bit is to expose it as an export. You can do this manually by tacking on module.exports = htmx at the bottom of htmx-bundle.js, but Rollup has a plugin for this called plugin-legacy made for older-style modules that don’t use imports/exports.

https://github.com/rollup/rollup-plugin-legacy

It’s overkill to use it just for this, but you could use it to pro grammatically apply exports to all the extensions so that they could be packed and imported separately from the main program if you like.

// rollup.config.js
import legacy from '@rollup/plugin-legacy'

export default {
  input: ['htmx-bundle.js'],
  output: {
    format: 'cjs',
    file: 'htmx-cjs.js',
  },
  plugins: [legacy({ 'htmx-bundle.js': 'htmx' })],
}

Then to test it, I made a single JS file where I attempted to import the generated htmx-cjs.js, included it into an index.html, and ran parcel index.html to bundle it:

<html>
  <body>
    <h1>Test</h1>
  </body>
  <script src="test.js"></script>
</html>
import htmx from './htmx-cjs'
console.log('got htmx', htmx)

const h1 = htmx.closest(document.querySelector('h1'), 'body')
console.log('closest h1', h1)

image

htmx-module

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to use NPM (and import/export modules) in JavaScript
NPM comes pre-installed with node.js. So, you don't need to worry about installing it manually, you just have to install node.js on your ......
Read more >
Downloading and installing packages locally - npm Docs
You can install a package locally if you want to depend on the package from your own module, using something like Node.js require...
Read more >
How to import and use npm modules - Coderslang
The default way of using npm modules in Node.js is called CommonJS . To import a module you can use the function require(id)...
Read more >
Installing and using libraries with npm - Node.js Basics [14]
Learn how to install external libraries and third party dependencies using npm. You'll learn how to use the ` npm install ` command...
Read more >
Using npm Packages - Meteor Guide
To use an npm package from a file in your application you import the name of the package: import moment from 'moment'; //...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found