This is the latest docs version
Quick Links
  • -Overview
  • -Language Features
  • -JS Interop
  • -Build System
Documentation
Language Manual
Reference for all language features
ReScript & React
First class bindings for ReactJS
GenType
Seamless TypeScript integration
Reanalyze
Dead Code & Termination analysis
Exploration
Packages
Explore third party libraries and bindings
Syntax Lookup
Discover all syntax constructs
APIPlaygroundBlogCommunity
  • Playground
  • Blog
  • Twitter
  • GitHub
  • Forum
Language Manual
Overview
  • Introduction
  • Installation
  • Migrate to v11
  • Editor Plugins
  • Try
Language Features
  • Overview
  • Let Binding
  • Type
  • Primitive Types
  • Tuple
  • Record
  • Object
  • Variant
  • Polymorphic Variant
  • Null, Undefined and Option
  • Array & List
  • Function
  • If-Else & Loops
  • Pipe
  • Pattern Matching / Destructuring
  • Mutation
  • JSX
  • Exception
  • Lazy Value
  • Promises
  • Async / Await
  • Tagged templates
  • Module
  • Import & Export
  • Attribute (Decorator)
  • Reserved Keywords
  • Equality and Comparison
Advanced Features
  • Extensible Variant
  • Scoped Polymorphic Types
JavaScript Interop
  • Interop Cheatsheet
  • Embed Raw JavaScript
  • Shared Data Types
  • External (Bind to Any JS Library)
  • Bind to JS Object
  • Bind to JS Function
  • Import from / Export to JS
  • Bind to Global JS Values
  • JSON
  • Inlining Constants
  • Use Illegal Identifier Names
  • Generate Converters & Helpers
  • Browser Support & Polyfills
  • Libraries & Publishing
  • TypeScript
Build System
  • Overview
  • Configuration
  • Configuration Schema
  • External Stdlib
  • Pinned Dependencies
  • Interop with JS Build Systems
    • Popular JS Build Systems
    • Use Loaders on ReScript Side
    • Getting Project's Dependencies
    • Run Script Per File Built
  • Performance
  • Warning Numbers
Guides
  • Converting from JS
Extra
  • Newcomer Examples
  • Project Structure
  • FAQ
Docs / Language Manual / Interop with JS Build Systems
Edit

Interop with JS Build Systems

If you come from JS, chances are that you already have a build system in your existing project. Here's an overview of the role rescript would play in your build pipeline, if you want to introduce some ReScript code.

Please try not to wrap rescript into your own incremental build framework. ReScript's compilation is very hard to get right, and you'll inevitably run into stale or badly performing builds (therefore erasing much of our value proposition) if you create your own meta layer on top.

Popular JS Build Systems

The JS ecosystem uses a few build systems: browserify, rollup, webpack, etc. The latter's probably the most popular of the three (as of 2019 =P). These build systems do both the compilation and the linking (aka, bundling many files into one or few files).

rescript only takes care of the compilation step; it maps one .res/.resi file into one JS output file. As such, in theory, no build system integration is needed from our side. From e.g. the webpack watcher's perspective, the JS files ReScript generates are almost equivalent to your hand-written JS files. We also recommend that you initially check in those ReScript-generated JS files, as this workflow means:

  • You can introduce ReScript silently into your codebase without disturbing existing infra.

  • You have a visual diff of the performance & correctness of your JS file when you update the .res files and the JS artifacts change.

  • You can let teammates hot-patch the JS files in emergency situations, without needing to first start learning ReScript.

  • You can remove ReScript completely from your codebase and things will still work (in case your company decides to stop using us for whatever reason).

For what it's worth, you can also turn rescript into an automated step in your build pipeline, e.g. into a Webpack loader; but such approach is error-prone and therefore discouraged.

Tips & Tricks

You can make ReScript JS files look even more idiomatic through the in-source + bs suffix config in rescript.json:

JSON
{ "package-specs": { "module": "commonjs", // or whatever module system your project uses "in-source": true }, "suffix": ".res.js" }

This will:

  • Generate the JS files alongside your ReScript source files.

  • Use the file extension .res.js, so that you can require these files on the JS side through require('./MyFile.res.js'), without needing a loader.

Use Loaders on ReScript Side

"What if my build system uses a CSS/png/whatever loader and I'd like to use it in ReScript?"

Loaders are indeed troublesome; in the meantime, please use e.g. %raw("require('./myStyles.css')") at the top of your file. This just uses raw to compile the snippet into an actual JS require.

Getting Project's Dependencies

rescript generates one MyFile.d file per MyFile source file; you'll find them in lib/bs. These are human readable, machine-friendly list of the dependencies of said MyFile. You can read into them for your purpose (though mind the IO overhead). Use these files instead of creating your own dependency graph; we did the hard work of tracking the dependencies as best as possible (including inner modules, opens, module names overlap, etc).

Run Script Per File Built

See js-post-build. Though please use it sparingly; if you hook up a node.js script after each file built, you'll incur the node startup time per file!

Pinned DependenciesPerformance

© 2024 The ReScript Project

Software and assets distribution powered by KeyCDN.

About
  • Community
  • ReScript Association
Find us on