search
HomeWeb Front-endJS TutorialNobuild with Rails and Importmap

The latest versions of Ruby on Rails have focused on simplicity across different aspects of the framework, accompanied by the promise to return to the “one-man framework” (where a single developer can effectively build and maintain an entire application).

Importmap Rails library is based on the principle that modern web browsers have caught up with the ECMAScript specification and can interpret ES Modules (ESM). As a web standard, Importmap allows you to control how JavaScript modules are resolved in the browser and manage dependencies and versions without the need to transpile or bundle the code sent to the browser.

How the Importmap Web Standard Works

It all starts with a script tag of type importmap defined in your application’s main layout or web page. Inside this tag, a JSON object defines aliases and their corresponding paths to the source code.

<script type="importmap">
  {
    "imports": {
      "application": "/assets/application.js",
      "local-time": "https://cdn.jsdelivr.net/npm/local-time@3.0.2/app/assets/javascripts/local-time.es2017-esm.min.js",
      "utils": "/assets/utils.js"
    }
  }
</script>

In the same map, you can mix library paths pointing to a CDN or using local resources. To use libraries from this map, reference the alias name.

<!-- Below the importmap script -->
<script type="module">import "application"</script>

And in your application.js, import needed dependencies:

// application.js

import LocalTime from "local-time";
LocalTime.start();

import "utils";

Importmap support is present in browsers Chrome 89 , Safari 16.4 , Firefox 108 , and Edge 89 . For older browsers, include a polyfill:

<script async src="https://ga.jspm.io/npm:es-module-shims@1.10.1/dist/es-module-shims.js"></script>

How Importmap Works in Ruby on Rails

Importmap functionality in Ruby on Rails follows the same standard described above and offers an easy way to create maps and version files. Using a web application named heroImage as an example (source code available on Github), let’s explore the implementation.

Nobuild with Rails and Importmap

When you create a new Rails 8 application, the importmap-rails gem is added and installed by default. A file config/importmap.rb is created where you can pin the JavaScript code needed in your application.

pin "application"

pin "@hotwired/turbo-rails", to: "turbo.min.js"
pin "@hotwired/stimulus", to: "stimulus.min.js"
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js"

pin_all_from "app/javascript/controllers", under: "controllers", preload: false

The pin keyword takes up to three arguments. The first one is required, as it is the alias of the JavaScript code. pin "application" is a shortcut for file application.js with alias application:

pin "application", to: "application.js"

When alias and file names differ, use the keyword to::

pin "@hotwired/turbo-rails", to: "turbo.min.js"

The pin_all_from keyword helps reference multiple files at once. The first argument is the path where the JavaScript files are located, and the under: argument prefixes the alias for each file. The generated alias uses the under prefix and the file name, like controllers/alert-controller for alert_controller.js file.

To visualize the Importmap JSON file, execute:

<script type="importmap">
  {
    "imports": {
      "application": "/assets/application.js",
      "local-time": "https://cdn.jsdelivr.net/npm/local-time@3.0.2/app/assets/javascripts/local-time.es2017-esm.min.js",
      "utils": "/assets/utils.js"
    }
  }
</script>

Rails resolves all JavaScript through the Propshaft gem, which resolves the physical path of the JavaScript code, maps to the /assets web path, and adds the digest to each file for better caching and invalidations.

Propshaft discovers physical paths from the asset’s configuration:

<!-- Below the importmap script -->
<script type="module">import "application"</script>

Ensure your files exist in any of the registered paths or add your own path to be discovered by Propshaft and Importmap.

Importmap in Rails allows you to specify how the browser should load JavaScript files. There are two options: preload (default) and no preload. Preload tells the browser to download files as soon as possible. Importmap generates a link tag with rel="modulepreload":

// application.js

import LocalTime from "local-time";
LocalTime.start();

import "utils";

If you set the preload argument to false, the link tag is not generated and the browser downloads the file when needed.

With Rails’ Importmap, you can also pin JavaScript code from a CDN using the to: argument for the URL:

<script async src="https://ga.jspm.io/npm:es-module-shims@1.10.1/dist/es-module-shims.js"></script>

The Importmap includes a CLI to pin or unpin JavaScript code into config/importmap.rb file. It also includes commands to update, audit, and inspect versions:

pin "application"

pin "@hotwired/turbo-rails", to: "turbo.min.js"
pin "@hotwired/stimulus", to: "stimulus.min.js"
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js"

pin_all_from "app/javascript/controllers", under: "controllers", preload: false

When using the pin command for a JavaScript package, instead of setting the to: argument to the CDN, Importmap resolves package dependencies and downloads the package and dependencies to vendor/javascript, allowing the Rails application to serve those files:

pin "application", to: "application.js"

This approach works well when your package has simple dependencies or well-defined dependencies in the JavaScript package. If that’s not the case, it becomes challenging to use with Importmap vendoring the code at vendor/javascript. It might work with the URL and manual dependency addition, or you can tweak the vendored code to make it work.

How to Work with Rails Gems - Engines - and Importmap?

There are two approaches to creating Ruby on Rails gems compatible with Importmap. The first approach allows your gem to provide JavaScript code, which you can choose to pin in the Importmap configuration. This is how the turbo-rails and stimulus-rails gems are implemented.

Place your JavaScript code in the app/assets/javascripts folder of your gem. You may need an additional process that minifies the JavaScript files and generates JavaScript map files. Then, inside the Engine class, define an initializer hook to declare your JavaScript code with Propshaft:

<script type="importmap">
  {
    "imports": {
      "application": "/assets/application.js",
      "local-time": "https://cdn.jsdelivr.net/npm/local-time@3.0.2/app/assets/javascripts/local-time.es2017-esm.min.js",
      "utils": "/assets/utils.js"
    }
  }
</script>

The second option uses an Importmap configuration file. If your engine has its layout template and the views are isolated from the host application, and the engine doesn’t need to share the JavaScript code with the host application, you can create an Importmap configuration file at config/importmap.rb, set your pins, place your JavaScript code at app/javascript, and configure the engine with an initializer.

Open your engine.rb Ruby file and add the Importmap configuration file and a sweeper:

<!-- Below the importmap script -->
<script type="module">import "application"</script>

Specify the Importmap to use in your engine’s layout template:

// application.js

import LocalTime from "local-time";
LocalTime.start();

import "utils";

For sharing JavaScript code with the host application, like Stimulus controllers, create a partial Importmap configuration file and set the engine to merge it with the main one in the host application.

Create an Importmap configuration file at config/importmap.rb and add the JavaScript pins to share with the host application. If you have dependencies for external packages, add those via a generator or installer to the host application:

<script async src="https://ga.jspm.io/npm:es-module-shims@1.10.1/dist/es-module-shims.js"></script>

Open your engine.rb file and add an initializer:

pin "application"

pin "@hotwired/turbo-rails", to: "turbo.min.js"
pin "@hotwired/stimulus", to: "stimulus.min.js"
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js"

pin_all_from "app/javascript/controllers", under: "controllers", preload: false

What are the Advantages of Using Importmap?

From a Ruby on Rails developer perspective, the main advantage of using Importmap is the freedom from requiring a JavaScript runtime-like node and freedom from the node_modules dependency.

Additionally, you don’t need an additional process in development mode to transpile and minify the JavaScript code. You rely on web standards to serve the code to the browser. Deploying your Rails application behind a reverse proxy offers several benefits. First, if you enable the HTTP/2 protocol, your browser can fetch multiple files with a single HTTP connection, and downloading many small JavaScript files won’t impact performance.

Nobuild with Rails and Importmap

Enabling your proxy to use gzip or brotli compression ensures you are sending very small files while maintaining readability when using browser developer tools. If you change one file, you only need to invalidate that specific file, which the browser will download. The browser knows that a file was modified because of the fingerprint that Propshaft adds to all files.

Using a reverse proxy like Thruster along with Puma offloads the assets serving from the Rails application. Thruster can cache assets and serve them when a client requests a file.

When Not to Use Importmap

There are cases where you should avoid using Importmap in a Rails application. If you are building a SPA application with React, Vue, or any other similar tool, there is a high likelihood you are writing your code with TypeScript. In this case, you should stick with the bundling strategy.

Additionally, if you need to support older browsers, bundling with code transpilation is a better option.

The above is the detailed content of Nobuild with Rails and Importmap. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
JavaScript's Core: Is It Built on C or C  ?JavaScript's Core: Is It Built on C or C ?May 05, 2025 am 12:07 AM

JavaScriptisnotbuiltonCorC ;it'saninterpretedlanguagethatrunsonenginesoftenwritteninC .1)JavaScriptwasdesignedasalightweight,interpretedlanguageforwebbrowsers.2)EnginesevolvedfromsimpleinterpreterstoJITcompilers,typicallyinC ,improvingperformance.

JavaScript Applications: From Front-End to Back-EndJavaScript Applications: From Front-End to Back-EndMay 04, 2025 am 12:12 AM

JavaScript can be used for front-end and back-end development. The front-end enhances the user experience through DOM operations, and the back-end handles server tasks through Node.js. 1. Front-end example: Change the content of the web page text. 2. Backend example: Create a Node.js server.

Python vs. JavaScript: Which Language Should You Learn?Python vs. JavaScript: Which Language Should You Learn?May 03, 2025 am 12:10 AM

Choosing Python or JavaScript should be based on career development, learning curve and ecosystem: 1) Career development: Python is suitable for data science and back-end development, while JavaScript is suitable for front-end and full-stack development. 2) Learning curve: Python syntax is concise and suitable for beginners; JavaScript syntax is flexible. 3) Ecosystem: Python has rich scientific computing libraries, and JavaScript has a powerful front-end framework.

JavaScript Frameworks: Powering Modern Web DevelopmentJavaScript Frameworks: Powering Modern Web DevelopmentMay 02, 2025 am 12:04 AM

The power of the JavaScript framework lies in simplifying development, improving user experience and application performance. When choosing a framework, consider: 1. Project size and complexity, 2. Team experience, 3. Ecosystem and community support.

The Relationship Between JavaScript, C  , and BrowsersThe Relationship Between JavaScript, C , and BrowsersMay 01, 2025 am 12:06 AM

Introduction I know you may find it strange, what exactly does JavaScript, C and browser have to do? They seem to be unrelated, but in fact, they play a very important role in modern web development. Today we will discuss the close connection between these three. Through this article, you will learn how JavaScript runs in the browser, the role of C in the browser engine, and how they work together to drive rendering and interaction of web pages. We all know the relationship between JavaScript and browser. JavaScript is the core language of front-end development. It runs directly in the browser, making web pages vivid and interesting. Have you ever wondered why JavaScr

Node.js Streams with TypeScriptNode.js Streams with TypeScriptApr 30, 2025 am 08:22 AM

Node.js excels at efficient I/O, largely thanks to streams. Streams process data incrementally, avoiding memory overload—ideal for large files, network tasks, and real-time applications. Combining streams with TypeScript's type safety creates a powe

Python vs. JavaScript: Performance and Efficiency ConsiderationsPython vs. JavaScript: Performance and Efficiency ConsiderationsApr 30, 2025 am 12:08 AM

The differences in performance and efficiency between Python and JavaScript are mainly reflected in: 1) As an interpreted language, Python runs slowly but has high development efficiency and is suitable for rapid prototype development; 2) JavaScript is limited to single thread in the browser, but multi-threading and asynchronous I/O can be used to improve performance in Node.js, and both have advantages in actual projects.

The Origins of JavaScript: Exploring Its Implementation LanguageThe Origins of JavaScript: Exploring Its Implementation LanguageApr 29, 2025 am 12:51 AM

JavaScript originated in 1995 and was created by Brandon Ike, and realized the language into C. 1.C language provides high performance and system-level programming capabilities for JavaScript. 2. JavaScript's memory management and performance optimization rely on C language. 3. The cross-platform feature of C language helps JavaScript run efficiently on different operating systems.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Atom editor mac version download

Atom editor mac version download

The most popular open source editor

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

EditPlus Chinese cracked version

EditPlus Chinese cracked version

Small size, syntax highlighting, does not support code prompt function

mPDF

mPDF

mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool