What Problem Do Import Maps Solve?
Let's say you want to use Lodash, a popular JavaScript utility library, in your project. Traditionally, you had a few options:
- Download and link directly:
<script src="lodash.min.js"></script>
<script src="your-app.js"></script>
This pollutes the global scope with _ and makes dependency management messy.
- Use a bundler like webpack:
This requires Node.js, complex build configurations, and a compilation step every time you change code.
Import maps solve this by letting you write clean, readable imports while the browser handles the complexity.
What Are Import Maps?
Import maps are a web standard that tells the browser where to find JavaScript modules. They let you write:
import _ from 'lodash';
The browser uses a special JSON configuration to map the short name 'lodash' to the actual location where the code lives.
Import maps work in all modern browsers.
Setting Up Lodash with NPM (No Bundler)
Let's create a simple example using npm packages directly - no webpack, no build step.
Click Tools -> npm Pacakges, enter lodash-es, add the package to your project.
After generation, PHPMaker will run npm update to download Lodash into node_modules/lodash-es/. We use lodash-es because it's the ES module version that works with import maps.
Create a Custom File with Include common files ENABLED. Enter the follows to the content of the file:
<h1>Lodash Import Map Demo</h1>
<p>Click a button to see Lodash in action:</p>
<button id="chunk-btn">Split Array into Chunks</button>
<button id="shuffle-btn">Shuffle Array</button>
<button id="sum-btn">Calculate Sum</button>
<div id="result" class="result">
Click a button to see the result!
</div>
<!-- The Import Map -->
<script<?= Nonce() ?> type="importmap">
{
"imports": {
"lodash": "./node_modules/lodash-es/lodash.js"
}
}
</script>
<!-- Your Application Code -->
<script<?= Nonce() ?> type="module">
import _ from 'lodash';
const result = document.getElementById('result');
const numbers = [1, 2, 3, 4, 5, 6, 7, 8];
document.getElementById('chunk-btn').addEventListener('click', () => {
const chunked = _.chunk(numbers, 3);
result.innerHTML = `
<strong>Original Array:</strong><br>
[${numbers.join(', ')}]<br><br>
<strong>Split into groups of 3:</strong><br>
${JSON.stringify(chunked)}
`;
});
document.getElementById('shuffle-btn').addEventListener('click', () => {
const shuffled = _.shuffle(numbers);
result.innerHTML = `
<strong>Original Array:</strong><br>
[${numbers.join(', ')}]<br><br>
<strong>Shuffled:</strong><br>
[${shuffled.join(', ')}]
`;
});
document.getElementById('sum-btn').addEventListener('click', () => {
const sum = _.sum(numbers);
result.innerHTML = `
<strong>Array:</strong><br>
[${numbers.join(', ')}]<br><br>
<strong>Sum:</strong><br>
${sum}
`;
});
</script>
Generate Scripts and run your site in browser. Go to the custom file and click the buttons to test.
Breaking It Down
The Import Map
<script type="importmap">
{
"imports": {
"lodash": "./node_modules/lodash-es/lodash.js"
}
}
</script>
This tells the browser: "When you see import ... from 'lodash', load the file from ./node_modules/lodash-es/lodash.js"
Important:
- The import map must come before any module scripts
- Use
type="importmap"(nottype="module") - The path is relative to your file
Using Lodash
<script type="module">
import _ from 'lodash';
const numbers = [1, 2, 3, 4, 5, 6];
const chunked = _.chunk(numbers, 2);
console.log(chunked); // [[1, 2], [3, 4], [5, 6]]
</script>
- Use
type="module"to enable imports - The
_variable contains all Lodash functions - No build step needed!
Why This Is Better Than Traditional Methods
Traditional way (global script):
<script src="lodash.min.js"></script>
<script>
// Lodash is now in global scope as "_"
const result = _.chunk([1, 2, 3], 2);
</script>
Global scope pollution
No module system
Hard to manage dependencies
Import Maps way:
<script type="importmap">
{"imports": {"lodash": "./node_modules/lodash-es/lodash.js"}}
</script>
<script type="module">
import _ from 'lodash';
const result = _.chunk([1, 2, 3], 2);
</script>
Clean imports
Module scope
Easy to manage
No build step needed
Common Beginner Mistakes
Wrong Lodash package:
npm install lodash # This won't work with import maps!
Use lodash-es:
npm install lodash-es # ES modules version
Wrong import map order:
<script type="module">
import _ from 'lodash'; // Error: import map not loaded yet!
</script>
<script type="importmap">
{"imports": {"lodash": "..."}}
</script>
Import map first:
<script type="importmap">
{"imports": {"lodash": "..."}}
</script>
<script type="module">
import _ from 'lodash'; // Works!
</script>
The Problems of Using Import Map with Vanilla JavaScript
You had to:
- Find the exact path in
node_modules - Manually add it to your import map
- Manage updates manually
For one package, this is manageable. But if you use many packages, it gets messy fast.
In next topic, I'll explain how Symfony makes this simpler.