-
Notifications
You must be signed in to change notification settings - Fork 294
Add tooling and library updates to 0.15.0 migration guide #424
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
236748d
3bb5310
371eefd
1683099
635a246
e0bfe4c
493bda7
044b9f8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,13 @@ | ||
| # PureScript 0.15 Migration Guide | ||
|
|
||
| ## ES modules migration guide | ||
| ## Tooling | ||
|
|
||
| - `purescript-psa` does not need to be updated. | ||
| - `spago` needs to be updated to `vT.B.D`. | ||
| - `pulp` needs to be updated to `v16.0.0`. | ||
| - `purs-tidy` needs to be updated to `vT.B.D`. | ||
|
|
||
| ## ES modules migration guide | ||
|
|
||
| ### tl;dr | ||
|
|
||
|
|
@@ -10,7 +17,7 @@ | |
|
|
||
| ### A little bit of background | ||
|
|
||
| In April 2021 the Node.js LTS version 10 reached end-of-life, which was the last version that did not yet support ES modules (ESM). This means, that all Node.js LTS and current versions support ES modules. And since all major browsers support ESM already since a long time, there is no need anymore in the JS ecosystem to support Common JS (CJS) and the community is advocating to [drop CJS support](https://github.com/sindresorhus/meta/discussions/15), which kinda makes sense. The community is following suit and is dropping its support for CJS, some notable examples are [remark](https://github.com/remarkjs/remark/tree/main/packages/remark#install), [`node-fetch`](https://github.com/node-fetch/node-fetch#commonjs) and [`framer-motion`](https://github.com/framer/motion) amongst many others. | ||
| In April 2021 the Node.js LTS version 10 reached end-of-life, which was the last version that did not yet support ES modules (ESM). This means, that all Node.js LTS and current versions support ES modules. And since all major browsers support ESM already since a long time, there is no need anymore in the JS ecosystem to support Common JS (CJS) and the community is advocating to [drop CJS support](https://github.com/sindresorhus/meta/discussions/15), which kinda makes sense. The community is following suit and is dropping its support for CJS, some notable examples are [remark](https://github.com/remarkjs/remark/tree/main/packages/remark#install), [`node-fetch`](https://github.com/node-fetch/node-fetch#commonjs) and [`framer-motion`](https://github.com/framer/motion) amongst many others. | ||
|
|
||
| What does that mean for Purescript v0.14? Well, a little bit of bad news, because Purescript v0.14 only supports CJS. Fortunately, there has been a [long-standing PR](https://github.com/purescript/purescript/pull/3791) to support ES modules in Purescript. So time to get this over the finish line and get ESM and | ||
|
|
||
|
|
@@ -32,13 +39,13 @@ However, this has a couple of implications that will need you to migrate your co | |
|
|
||
|
|
||
| * v0.15 drops support for Node.js versions < 12 | ||
|
|
||
| This is just the logical consequence of Node.js versions < 12 having reached EOL and not supporting ESM. More on this here: | ||
|
|
||
| [How can I use Purescript on Node.js?](#how-can-i-update-cjs-to-esm) | ||
|
|
||
| * v0.15 drops `purs bundle` and relies on an external bundlers | ||
|
|
||
| Yes, you heard right. The Purescript compiler no longer comes with a built-in `bundle` command. `purs bundle` was already broken in a couple of ways, didn't do a great job on bundle size, and was basically unmaintained. Updating `purs bundle` to ESM would have required a considerable amount of work, taking time away from the compiler team to work on more urgent matters in the compiler. | ||
|
|
||
| Therefore, v0.15 relies on an external bundler like `esbuild`, `webpack` or `parcel`. And that is good news because these tools are used industry-wide and do a much better job on bundling than `purs bundle`. You will see significantly improved bundle sizes with v0.15, like e.g. for [purescript-halogen template](https://github.com/purescript-halogen/purescript-halogen-template): | ||
|
|
@@ -99,7 +106,7 @@ However, this has a couple of implications that will need you to migrate your co | |
| "use strict"; | ||
| $PS["Main"] = $PS["Main"] || {}; | ||
| var exports = $PS["Main"]; | ||
| var Effect_Console = $PS["Effect.Console"]; | ||
| var Effect_Console = $PS["Effect.Console"]; | ||
| var main = Effect_Console.log("\ud83c\udf5d"); | ||
| exports["main"] = main; | ||
| })(PS); | ||
|
|
@@ -112,11 +119,13 @@ However, this has a couple of implications that will need you to migrate your co | |
|
|
||
| ### How can I update CJS to ESM? | ||
|
|
||
| When you are writing JS FFI the most common situations where you will see changes are: | ||
| Most of the below changes can be automated (see next section), but this section describes what changes need to be made in more detail. | ||
|
|
||
| When you are writing JS FFI the most common situations where you will see changes are: | ||
|
|
||
| * Importing a module | ||
|
|
||
| In v0.14 you had to import a module using `require` | ||
| In v0.14 you had to import a module using `require` | ||
|
|
||
| ```javascript | ||
| const mymodule = require('mymodule') | ||
|
|
@@ -137,11 +146,19 @@ When you are writing JS FFI the most common situations where you will see change | |
| exports.greet = function() { return "hello " + world } | ||
| ``` | ||
|
|
||
| In v0.15 you need to use `export` | ||
| In v0.15 you need to use `export` | ||
| ```javascript | ||
| export const world = "🗺" | ||
|
|
||
| export function greet() { return "hello " + world } | ||
|
|
||
| // Sometimes, defining the function and then exporting it under | ||
| // a different name is needed to prevent issues with JavaScript | ||
| // keywords. For example, we might use the below FFI | ||
| // to export a function named `new` | ||
| // foreign import new :: Effect SomeObject | ||
| const newImpl = function () { return new SomeObject; } | ||
| export { newImpl as new }; | ||
| ``` | ||
|
|
||
| Fortunately, there are tools that can automatically perform this conversion for you in most of the cases. | ||
|
|
@@ -167,6 +184,7 @@ https://github.com/lebab/lebab#unsafe-transforms | |
|
|
||
| In general though it works well in most of the cases. | ||
|
|
||
| See also the ["Migrate to ES Modules"](https://github.com/JordanMartinez/purescript-ecosystem-update/blob/master/src/bash/lib/migrateFfiToEs6.sh) script used in the ecosystem updates for inspiration. | ||
|
|
||
| Another option you can try is [`cjstoesm`](https://github.com/wessberg/cjstoesm). | ||
|
|
||
|
|
@@ -182,7 +200,7 @@ import { main } from 'output/Main/index.js' | |
| main() | ||
| ``` | ||
|
|
||
| and run | ||
| and run | ||
| ```bash | ||
| node index.js | ||
| # or if you are on Node.js 12 | ||
|
|
@@ -212,20 +230,20 @@ For a full discussion see [the github issue](https://github.com/working-group-pu | |
|
|
||
| See [`spago` documentation](https://github.com/purescript/spago#bundle-a-project-into-a-single-js-file). | ||
|
|
||
| Basic usage: | ||
| Basic usage: | ||
| ```bash | ||
| spago bundle-app # bundle for the browser | ||
| spago bundle-app # bundle for the browser | ||
| spago bundle-app --platform node # bundle for node | ||
| spago bundle-app --minify # minified bundle for the browser | ||
| spago bundle-app --minify # minified bundle for the browser | ||
| spago bundle-app --platform node --minify # minified bundle for node | ||
|
|
||
| spago bundle-module # bundle for the browser | ||
| spago bundle-module # bundle for the browser | ||
| spago bundle-module --platform node # bundle for node | ||
| spago bundle-module --minify # minified bundle for the browser | ||
| spago bundle-module --minify # minified bundle for the browser | ||
| spago bundle-module --platform node --minify # minified bundle for node | ||
| ``` | ||
|
|
||
| #### Using `esbuild` to bundle | ||
| #### Using `esbuild` to bundle | ||
|
|
||
| See [`esbuild` documentation](https://esbuild.github.io/). | ||
|
|
||
|
|
@@ -257,3 +275,49 @@ Basic usage: | |
| parcel build index.html --no-source-maps --no-optimize --no-scope-hoist --dist-dir "dist/" # bundle for the browser | ||
| parcel build index.html --no-source-maps --dist-dir "dist/" # minified bundle for the browser | ||
| ``` | ||
|
|
||
| ## Breaking Changes Made in Core Libraries | ||
|
|
||
| ### Changes affecting multiple libraries | ||
|
|
||
| - Migrated all FFI to ES modules and dropped support for CommonJS modules. | ||
| - Removed all kind-specific Proxy types (e.g. `SProxy`, `Proxy2`, `Proxy3`, `RLProxy`, etc.) | ||
| - Replace usage of such types with `Type.Proxy (Proxy(..))`. | ||
| - Removed `MonadZero` type class and all of its deprecated instances. | ||
|
|
||
| ### `purescript-prelude` changes | ||
|
|
||
| - The data type, `NoConstructors`, often used in `Generic`-related code, was changed to newtype `Void`, enabling one to unwrap the newtype and use `absurd`. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If this is non-breaking then I'm not sure it needs to be included; if it is breaking then we can keep it.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure it's breaking, but it's been labeled as such and does actually enable type class instances to exist that weren't possible before. So, I do think it deserves a mention because many do rely upon |
||
|
|
||
| ### `purescript-ordered-collections`: update on `Map`'s `Semigroup` instance | ||
|
|
||
| This section has yet to be written. Below is what was written in the v0.14.x guide. | ||
|
|
||
| - Changes we will be making in future releases: | ||
| - v0.14.0 | ||
| - `Data.Map.Unbiased` - added | ||
| - `Data.Map`'s `Semigroup` instance unchanged but a deprecation notice is added, warning of future change | ||
| - v0.15.0 | ||
| - `Data.Map.Unbiased` - deprecated | ||
| - `Data.Map`'s `Semigroup` instance is changed to `Data.Map.Unbiased` implementation. A deprecation notice is still shown, warning of the change. | ||
| - v0.16.0 | ||
| - `Data.Map.Unbiased` - removed | ||
| - `Data.Map` - warning on `Semigroup` instance is removed | ||
|
|
||
| See [Unbiasing the Semigroup instance for Map](https://discourse.purescript.org/t/unbiasing-the-semigroup-instance-for-map/1935) and [purescript/purescript-ordered-collections#38](https://github.com/purescript/purescript-ordered-collections/pull/38) for more context. | ||
|
|
||
| ### `purescript-foreign-object`'s `Semigroup` instance was changed | ||
|
|
||
| This section has yet to be written. Including here because it relates to the Map discussion above. | ||
|
|
||
| ## Breaking Changes in the `purescript-contrib` libraries | ||
|
|
||
| This section has yet to be written | ||
|
|
||
| ## Breaking Changes in the `purescript-node` libraries | ||
|
|
||
| This section has yet to be written | ||
|
|
||
| ## Breaking Changes in the `purescript-web` libraries | ||
|
|
||
| This section has yet to be written | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe note "If you are using any of these types, replace them with
Proxyinstead."