├── .flowconfig ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── examples ├── commonjs │ ├── .gitignore │ ├── README.md │ ├── bsconfig.json │ ├── package.json │ ├── src │ │ ├── add.re │ │ ├── add_test.re │ │ ├── fib.ml │ │ ├── fib.mli │ │ └── print.re │ └── webpack.config.js └── es6 │ ├── .gitignore │ ├── README.md │ ├── bsconfig.json │ ├── package.json │ ├── src │ ├── add.re │ ├── fib.ml │ ├── fib.mli │ └── print.re │ └── webpack.config.js ├── flow-typed ├── babel-core.js ├── glob.js ├── loader-utils.js ├── reasonable-flowgen.js └── webpack.js ├── package.json ├── packages ├── bs-loader │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── index.js │ ├── package.json │ └── test │ │ ├── insource │ │ ├── bsconfig.json │ │ ├── fixtures │ │ │ ├── add.js │ │ │ ├── add.re │ │ │ ├── dec.js │ │ │ ├── fib.js │ │ │ ├── fib.ml │ │ │ └── fib.mli │ │ ├── package.json │ │ └── webpack.test.js │ │ ├── jest-esm │ │ ├── bsconfig.json │ │ ├── fixtures │ │ │ ├── add.js │ │ │ ├── add.re │ │ │ ├── adder.js │ │ │ ├── adder.re │ │ │ ├── dec.js │ │ │ ├── fib.js │ │ │ ├── fib.ml │ │ │ └── fib.mli │ │ ├── package.json │ │ └── test.js │ │ ├── no-config │ │ ├── bsconfig.json │ │ ├── fixtures │ │ │ ├── add.js │ │ │ ├── add.re │ │ │ ├── dec.js │ │ │ ├── fib.js │ │ │ ├── fib.ml │ │ │ └── fib.mli │ │ ├── package.json │ │ └── webpack.test.js │ │ ├── simple │ │ ├── bsconfig.json │ │ ├── fixtures │ │ │ ├── add.js │ │ │ ├── add.re │ │ │ ├── dec.js │ │ │ ├── fib.js │ │ │ ├── fib.ml │ │ │ └── fib.mli │ │ ├── package.json │ │ └── webpack.test.js │ │ ├── warnings-super │ │ ├── bsconfig.json │ │ ├── fixtures │ │ │ └── index.re │ │ ├── package.json │ │ └── webpack.test.js │ │ └── warnings │ │ ├── bsconfig.json │ │ ├── fixtures │ │ └── index.re │ │ ├── package.json │ │ └── webpack.test.js ├── bsb-js │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── index.js │ ├── package.json │ └── utils.js ├── read-bsconfig │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── __tests__ │ │ ├── bsconfig.json │ │ └── read.js │ ├── index.js │ └── package.json ├── reason-types-webpack-plugin │ ├── .gitignore │ ├── .npmignore │ ├── LICENSE │ ├── README.md │ ├── example │ │ ├── .flowconfig │ │ ├── .gitignore │ │ ├── .merlin │ │ ├── bsconfig.json │ │ ├── package.json │ │ ├── src │ │ │ ├── index.js │ │ │ ├── math.js │ │ │ └── print_math.re │ │ └── webpack.config.js │ ├── index.js │ └── package.json └── reason-webpack-plugin │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── example │ ├── .gitignore │ ├── .merlin │ ├── bsconfig.json │ ├── package.json │ ├── src │ │ ├── index.js │ │ └── print.re │ └── webpack.config.js │ ├── index.js │ └── package.json └── yarn.lock /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | .*/node_modules/bs-platform/.* 3 | .*/example/.* 4 | 5 | [include] 6 | 7 | [libs] 8 | 9 | [lints] 10 | all=warn 11 | untyped-type-import=error 12 | 13 | [options] 14 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue 15 | emoji=true 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | *.log 4 | .vscode/ -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | os: 2 | - linux 3 | - osx 4 | 5 | language: node_js 6 | 7 | node_js: 8 | - "node" 9 | 10 | cache: yarn 11 | 12 | before_install: 13 | - curl -o- -L https://yarnpkg.com/install.sh | bash 14 | - export PATH="$HOME/.yarn/bin:$PATH" 15 | 16 | install: 17 | - "npm i -g bs-platform" 18 | - "yarn install" 19 | - "npm link bs-platform" 20 | 21 | test: 22 | - "yarn test" 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Ryan Delaney 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # bs-loader [![Build Status](https://travis-ci.org/reasonml-community/bs-loader.svg?branch=master)](https://travis-ci.org/reasonml-community/bs-loader) 2 | > Bucklescript loader for Webpack 3 | 4 | --- 5 | **This library is in maintanence mode. Instead of using bs-loader we recommend 6 | using bsb' new in-source builds in conjunction with .bs.js extensions:** 7 | 8 | ```json 9 | // bcsconfig.json 10 | { 11 | "package-specs": { 12 | "module": "commonjs", 13 | "in-source": true 14 | }, 15 | "suffix": ".bs.js", 16 | } 17 | ``` 18 | 19 | --- 20 | This works with both Reason and OCaml files 21 | 22 | ## Installation 23 | 24 | ``` 25 | npm install bs-loader 26 | ``` 27 | 28 | ## [Example](https://github.com/reasonml-community/bs-loader/blob/master/examples) 29 | 30 | ## Setting up Bucklescript 31 | 32 | First install `bs-platform` into the project: 33 | 34 | ``` 35 | $ npm i -D bs-platform 36 | ``` 37 | 38 | Create a `bsconfig.json` for Bucklescript: 39 | 40 | ```json 41 | /* bsconfig.json */ 42 | { 43 | "name": "hello", 44 | "sources": [ 45 | "src" 46 | ], 47 | "bs-dependencies": [ 48 | "reason-react" 49 | ], 50 | "reason": { 51 | "react-jsx": 2 52 | } 53 | } 54 | ``` 55 | 56 | We will also need `reason-react`, and `bs-platform`. You can install `bs-platform` globally and 57 | use `npm link` to the link the binary, or install `bs-platform` as a devDependency. 58 | Your `package.json` should look something like this: 59 | 60 | ```json 61 | /* package.json */ 62 | { 63 | "name": "reason-webpack", 64 | "private": true, 65 | "version": "1.0.0", 66 | "description": "", 67 | "scripts": { 68 | "build": "webpack" 69 | }, 70 | "author": "", 71 | "license": "ISC", 72 | "devDependencies": { 73 | "bs-loader": "^1.0.0", 74 | "reason-react": "0.1.3", 75 | "webpack": "^2.2.1" 76 | }, 77 | "dependencies": { 78 | "react": "^15.4.2", 79 | "react-dom": "^15.4.2" 80 | } 81 | } 82 | 83 | ``` 84 | 85 | ## Using the loader 86 | 87 | To use the loader you must: 88 | * Register the `.re` and `.ml` extensions with Webpack 89 | * Configure `.re` and `.ml` to use the loader 90 | 91 | An example config would look like: 92 | 93 | ```js 94 | // webpack.config.js 95 | const path = require('path') 96 | 97 | module.exports = { 98 | // Entry file can be a Reason or OCaml file 99 | entry: './src/entry.re', 100 | output: { 101 | filename: 'out.js', 102 | path: path.resolve(__dirname, 'build') 103 | }, 104 | module: { 105 | rules: [ 106 | // Set up Reason and OCaml files to use the loader 107 | { test: /\.(re|ml)$/, use: 'bs-loader' }, 108 | ] 109 | }, 110 | resolve: { 111 | // Add .re and .ml to the list of extensions webpack recognizes 112 | extensions: ['.re', '.ml', '.js'] 113 | } 114 | } 115 | ``` 116 | 117 | ## Usage with Jest 118 | 119 | `bs-loader` includes a transform for usage with Jest. This lets Jest run 120 | Reason and OCaml files as tests. An example Jest configuration using `bs-loader`: 121 | 122 | ``` 123 | "jest": { 124 | "moduleFileExtensions": [ 125 | "re", 126 | "js", 127 | "ml" 128 | ], 129 | "testMatch": [ 130 | "**/src/*_test.re" 131 | ], 132 | "transform": { 133 | ".(re|ml)": "bs-loader" 134 | } 135 | } 136 | ``` 137 | 138 | ## Options 139 | 140 | Most of these settings are inferred from your `bsconfig.json`. These are available 141 | for manual override, but might go away in the future. 142 | 143 | ### `module` 144 | 145 | To tell Webpack to load a module type that isn't JS (for example, `amd` or `goog`) 146 | give the loader a `module` option. For example, to use AMD modules produced by Bucklescript, 147 | use the config 148 | 149 | ```js 150 | { test: /\.(re|ml)$/, use: 'bs-loader?module=amd' } 151 | ``` 152 | 153 | ### `inSource` 154 | 155 | To use bs-loader with [bsb's in-souce builds](https://bucklescript.github.io/bucklescript/Manual.html#_in_source_build_support_since_1_9_0), 156 | add the `inSource` option to your loader config: 157 | 158 | ```js 159 | { 160 | test: /\.(re|ml)$/, 161 | use: { 162 | loader: 'bs-loader', 163 | options: { 164 | module: 'es6', 165 | inSource: true 166 | } 167 | } 168 | } 169 | ``` 170 | 171 | ### `cwd` 172 | 173 | This option specifies what directory to run `bsb` from. For example, to 174 | run `bsb` from the same directory as your webpack config, use: 175 | 176 | ```js 177 | { 178 | test: /\.(re|ml)$/, 179 | use: { 180 | loader: 'bs-loader', 181 | options: { 182 | cwd: __dirname 183 | } 184 | } 185 | } 186 | ``` 187 | 188 | ### `showWarnings` 189 | 190 | Controls whether `bsb` compile warnings are shown. Defaults to `true`. 191 | -------------------------------------------------------------------------------- /examples/commonjs/.gitignore: -------------------------------------------------------------------------------- 1 | lib/ 2 | node_modules/ 3 | build/ 4 | .merlin 5 | -------------------------------------------------------------------------------- /examples/commonjs/README.md: -------------------------------------------------------------------------------- 1 | # bs-loader example 2 | 3 | This is an example use case for `bs-loader` 4 | 5 | * [__`package.json`__](https://github.com/rrdelaney/bs-loader/blob/master/example/package.json) 6 | * [__Webpack Config__](https://github.com/rrdelaney/bs-loader/blob/master/example/webpack.config.js) 7 | * [__Bucklescript Config__](https://github.com/rrdelaney/bs-loader/blob/master/example/bsconfig.json) 8 | 9 | ## Building the example 10 | 11 | ``` 12 | npm run build 13 | ``` 14 | 15 | You'll be able to see the Bucklescript output in `lib/` and the Webpack output in `build/` 16 | -------------------------------------------------------------------------------- /examples/commonjs/bsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hello", 3 | "sources": ["src"], 4 | "bs-dependencies": ["reason-react", "bs-jest"], 5 | "reason": { 6 | "react-jsx": 2 7 | }, 8 | "refmt": 3 9 | } 10 | -------------------------------------------------------------------------------- /examples/commonjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reason-webpack-commonjs-example", 3 | "private": true, 4 | "version": "1.1.0", 5 | "description": "", 6 | "scripts": { 7 | "build": "webpack", 8 | "test": "jest" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "bs-jest": "^0.1.0", 14 | "bs-loader": "^1.8.0", 15 | "jest": "^20.0.4", 16 | "reason-react": "^0.2.1", 17 | "webpack": "^2.2.1", 18 | "webpack-dev-server": "^2.4.5" 19 | }, 20 | "dependencies": { 21 | "react": "^15.4.2", 22 | "react-dom": "^15.4.2" 23 | }, 24 | "jest": { 25 | "moduleFileExtensions": ["re", "js", "ml"], 26 | "testMatch": ["**/src/*_test.re"], 27 | "transform": { 28 | ".(re|ml)": "bs-loader" 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /examples/commonjs/src/add.re: -------------------------------------------------------------------------------- 1 | let add = (x, y) => x + y; 2 | -------------------------------------------------------------------------------- /examples/commonjs/src/add_test.re: -------------------------------------------------------------------------------- 1 | open Jest; 2 | 3 | test( 4 | "addition", 5 | () => { 6 | open Expect; 7 | let num1 = 1; 8 | let num2 = 3; 9 | expect(Add.add(num1, num2)) |> toBe(4) 10 | } 11 | ); 12 | -------------------------------------------------------------------------------- /examples/commonjs/src/fib.ml: -------------------------------------------------------------------------------- 1 | let fib n = 2 | let rec aux n a b = 3 | if n = 0 then a 4 | else 5 | aux (n - 1) b (a+b) 6 | in aux n 1 1 7 | -------------------------------------------------------------------------------- /examples/commonjs/src/fib.mli: -------------------------------------------------------------------------------- 1 | val fib : int -> int 2 | -------------------------------------------------------------------------------- /examples/commonjs/src/print.re: -------------------------------------------------------------------------------- 1 | let f1 = Fib.fib(10); 2 | 3 | let f2 = Fib.fib(20); 4 | 5 | let sum = Add.add(f1, f2); 6 | 7 | Js.log(sum); 8 | 9 | let elem =
; 10 | -------------------------------------------------------------------------------- /examples/commonjs/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | 3 | module.exports = { 4 | entry: './src/print.re', 5 | output: { 6 | filename: 'out.js', 7 | path: path.resolve(__dirname, 'build') 8 | }, 9 | module: { 10 | rules: [ 11 | { test: /\.(re|ml)$/, use: 'bs-loader' }, 12 | ] 13 | }, 14 | resolve: { 15 | extensions: ['.re', '.ml', '.js'] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/es6/.gitignore: -------------------------------------------------------------------------------- 1 | lib/ 2 | node_modules/ 3 | build/ 4 | .merlin 5 | -------------------------------------------------------------------------------- /examples/es6/README.md: -------------------------------------------------------------------------------- 1 | # bs-loader example 2 | 3 | This is an example use case for `bs-loader` 4 | 5 | * [__`package.json`__](https://github.com/rrdelaney/bs-loader/blob/master/example/package.json) 6 | * [__Webpack Config__](https://github.com/rrdelaney/bs-loader/blob/master/example/webpack.config.js) 7 | * [__Bucklescript Config__](https://github.com/rrdelaney/bs-loader/blob/master/example/bsconfig.json) 8 | 9 | ## Building the example 10 | 11 | ``` 12 | npm run build 13 | ``` 14 | 15 | You'll be able to see the Bucklescript output in `lib/` and the Webpack output in `build/` 16 | -------------------------------------------------------------------------------- /examples/es6/bsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hello", 3 | "sources": ["src"], 4 | "bs-dependencies": ["reason-react"], 5 | "reason": { 6 | "react-jsx": 2 7 | }, 8 | "package-specs": ["es6"], 9 | "bsc-flags": ["-bs-super-errors"], 10 | "refmt": 3 11 | } 12 | -------------------------------------------------------------------------------- /examples/es6/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reason-webpack-es6-example", 3 | "private": true, 4 | "version": "1.1.0", 5 | "description": "", 6 | "scripts": { 7 | "build": "webpack" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "bs-loader": "^1.8.0", 13 | "jest": "^20.0.4", 14 | "reason-react": "^0.2.1", 15 | "webpack": "^3.0.0", 16 | "webpack-dev-server": "^2.5.0" 17 | }, 18 | "dependencies": { 19 | "react": "^15.6.1", 20 | "react-dom": "^15.6.1" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /examples/es6/src/add.re: -------------------------------------------------------------------------------- 1 | let add = (x, y) => x + y; 2 | -------------------------------------------------------------------------------- /examples/es6/src/fib.ml: -------------------------------------------------------------------------------- 1 | let fib n = 2 | let rec aux n a b = 3 | if n = 0 then a 4 | else 5 | aux (n - 1) b (a+b) 6 | in aux n 1 1 7 | -------------------------------------------------------------------------------- /examples/es6/src/fib.mli: -------------------------------------------------------------------------------- 1 | val fib : int -> int 2 | -------------------------------------------------------------------------------- /examples/es6/src/print.re: -------------------------------------------------------------------------------- 1 | let f1 = Fib.fib(10); 2 | 3 | let f2 = Fib.fib(20); 4 | 5 | let sum = Add.add(f1, f2); 6 | 7 | Js.log(sum); 8 | 9 | let elem =
; 10 | -------------------------------------------------------------------------------- /examples/es6/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | 3 | module.exports = { 4 | entry: './src/print.re', 5 | output: { 6 | filename: 'out.js', 7 | path: path.resolve(__dirname, 'build') 8 | }, 9 | module: { 10 | rules: [ 11 | { 12 | test: /\.(re|ml)$/, 13 | use: [ 14 | { 15 | loader: 'bs-loader', 16 | options: { 17 | module: 'es6' 18 | } 19 | } 20 | ] 21 | } 22 | ] 23 | }, 24 | 25 | resolve: { 26 | extensions: ['.re', '.ml', '.js'] 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /flow-typed/babel-core.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | declare module '@babel/core' { 4 | declare type BabelOptions = { 5 | plugins: string[], 6 | } 7 | 8 | declare type BabelOutput = { 9 | code: string, 10 | } 11 | 12 | declare export function transform( 13 | code: string, 14 | options: BabelOptions, 15 | ): BabelOutput 16 | } 17 | -------------------------------------------------------------------------------- /flow-typed/glob.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | declare module 'glob' { 4 | declare type GlobFn = { 5 | ( 6 | sources: string, 7 | callback: (err: null | Error, matches: string[]) => void 8 | ): void, 9 | sync: (sources: string) => string[] 10 | } 11 | 12 | declare module.exports: GlobFn 13 | } 14 | -------------------------------------------------------------------------------- /flow-typed/loader-utils.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | declare module 'loader-utils' { 4 | declare export function getOptions(context: any): { [key: string]: any } 5 | } 6 | -------------------------------------------------------------------------------- /flow-typed/reasonable-flowgen.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | declare module 'reasonable-flowgen' { 4 | declare type FlowgenCompiler = { 5 | compileDefinitionFile(filename: string): string, 6 | compileDefinitionString(src: string): string 7 | } 8 | 9 | declare module.exports: { 10 | default: FlowgenCompiler 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /flow-typed/webpack.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | declare module 'webpack' { 4 | declare export type WebpackLoaderThis = { 5 | async: () => (err: Error | null, res: string | null) => void, 6 | context: string, 7 | addContextDependency: (dep: string) => void, 8 | resourcePath: string, 9 | _compilation: { [key: string]: any }, 10 | emitError: (err: Error) => void, 11 | emitWarning: (err: Error) => void 12 | } 13 | 14 | declare export type WebpackCompilerInstance = { 15 | plugin: ( 16 | event: string, 17 | callback: (compilation: any, callback: () => void) => void | Promise 18 | ) => void, 19 | context: string 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reason-tooling", 3 | "private": true, 4 | "devDependencies": { 5 | "flow-bin": "^0.82.0", 6 | "jest-cli": "^23.6.0" 7 | }, 8 | "scripts": { 9 | "test": "flow && jest" 10 | }, 11 | "workspaces": [ 12 | "packages/bs-loader", 13 | "packages/read-bsconfig", 14 | "packages/bsb-js", 15 | "packages/reason-types-webpack-plugin", 16 | "packages/reason-webpack-plugin" 17 | ], 18 | "jest": { 19 | "projects": [ 20 | "packages/bs-loader", 21 | "packages/read-bsconfig", 22 | "packages/bsb-js", 23 | "packages/reason-webpack-plugin" 24 | ] 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/bs-loader/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | *.log 4 | test/*/lib 5 | test/*/output 6 | test/*/.merlin 7 | -------------------------------------------------------------------------------- /packages/bs-loader/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Ryan Delaney 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/bs-loader/README.md: -------------------------------------------------------------------------------- 1 | # bs-loader [![Build Status](https://travis-ci.org/reasonml-community/bs-loader.svg?branch=master)](https://travis-ci.org/reasonml-community/bs-loader) 2 | > Bucklescript loader for Webpack 3 | 4 | --- 5 | **This library is in maintanence mode. Instead of using bs-loader we recommend 6 | using bsb' new in-source builds in conjunction with .bs.js extensions:** 7 | 8 | ```json 9 | // bcsconfig.json 10 | { 11 | "package-specs": { 12 | "module": "commonjs", 13 | "in-source": true 14 | }, 15 | "suffix": ".bs.js", 16 | } 17 | ``` 18 | 19 | --- 20 | This works with both Reason and OCaml files 21 | 22 | ## Installation 23 | 24 | ``` 25 | npm install bs-loader 26 | ``` 27 | 28 | ## [Example](https://github.com/reasonml-community/bs-loader/blob/master/examples) 29 | 30 | ## Setting up Bucklescript 31 | 32 | First install `bs-platform` into the project: 33 | 34 | ``` 35 | $ npm i -D bs-platform 36 | ``` 37 | 38 | Create a `bsconfig.json` for Bucklescript: 39 | 40 | ```json 41 | /* bsconfig.json */ 42 | { 43 | "name": "hello", 44 | "sources": [ 45 | "src" 46 | ], 47 | "bs-dependencies": [ 48 | "reason-react" 49 | ], 50 | "reason": { 51 | "react-jsx": 2 52 | } 53 | } 54 | ``` 55 | 56 | We will also need `reason-react`, and `bs-platform`. You can install `bs-platform` globally and 57 | use `npm link` to the link the binary, or install `bs-platform` as a devDependency. 58 | Your `package.json` should look something like this: 59 | 60 | ```json 61 | /* package.json */ 62 | { 63 | "name": "reason-webpack", 64 | "private": true, 65 | "version": "1.0.0", 66 | "description": "", 67 | "scripts": { 68 | "build": "webpack" 69 | }, 70 | "author": "", 71 | "license": "ISC", 72 | "devDependencies": { 73 | "bs-loader": "^1.0.0", 74 | "reason-react": "0.1.3", 75 | "webpack": "^2.2.1" 76 | }, 77 | "dependencies": { 78 | "react": "^15.4.2", 79 | "react-dom": "^15.4.2" 80 | } 81 | } 82 | 83 | ``` 84 | 85 | ## Using the loader 86 | 87 | To use the loader you must: 88 | * Register the `.re` and `.ml` extensions with Webpack 89 | * Configure `.re` and `.ml` to use the loader 90 | 91 | An example config would look like: 92 | 93 | ```js 94 | // webpack.config.js 95 | const path = require('path') 96 | 97 | module.exports = { 98 | // Entry file can be a Reason or OCaml file 99 | entry: './src/entry.re', 100 | output: { 101 | filename: 'out.js', 102 | path: path.resolve(__dirname, 'build') 103 | }, 104 | module: { 105 | rules: [ 106 | // Set up Reason and OCaml files to use the loader 107 | { test: /\.(re|ml)$/, use: 'bs-loader' }, 108 | ] 109 | }, 110 | resolve: { 111 | // Add .re and .ml to the list of extensions webpack recognizes 112 | extensions: ['.re', '.ml', '.js'] 113 | } 114 | } 115 | ``` 116 | 117 | ## Usage with Jest 118 | 119 | `bs-loader` includes a transform for usage with Jest. This lets Jest run 120 | Reason and OCaml files as tests. An example Jest configuration using `bs-loader`: 121 | 122 | ``` 123 | "jest": { 124 | "moduleFileExtensions": [ 125 | "re", 126 | "js", 127 | "ml" 128 | ], 129 | "testMatch": [ 130 | "**/src/*_test.re" 131 | ], 132 | "transform": { 133 | ".(re|ml)": "bs-loader" 134 | } 135 | } 136 | ``` 137 | 138 | ## Options 139 | 140 | Most of these settings are inferred from your `bsconfig.json`. These are available 141 | for manual override, but might go away in the future. 142 | 143 | ### `module` 144 | 145 | To tell Webpack to load a module type that isn't JS (for example, `amd` or `goog`) 146 | give the loader a `module` option. For example, to use AMD modules produced by Bucklescript, 147 | use the config 148 | 149 | ```js 150 | { test: /\.(re|ml)$/, use: 'bs-loader?module=amd' } 151 | ``` 152 | 153 | ### `inSource` 154 | 155 | To use bs-loader with [bsb's in-souce builds](https://bucklescript.github.io/bucklescript/Manual.html#_in_source_build_support_since_1_9_0), 156 | add the `inSource` option to your loader config: 157 | 158 | ```js 159 | { 160 | test: /\.(re|ml)$/, 161 | use: { 162 | loader: 'bs-loader', 163 | options: { 164 | module: 'es6', 165 | inSource: true 166 | } 167 | } 168 | } 169 | ``` 170 | 171 | ### `cwd` 172 | 173 | This option specifies what directory to run `bsb` from. For example, to 174 | run `bsb` from the same directory as your webpack config, use: 175 | 176 | ```js 177 | { 178 | test: /\.(re|ml)$/, 179 | use: { 180 | loader: 'bs-loader', 181 | options: { 182 | cwd: __dirname 183 | } 184 | } 185 | } 186 | ``` 187 | 188 | ### `showWarnings` 189 | 190 | Controls whether `bsb` compile warnings are shown. Defaults to `true`. 191 | -------------------------------------------------------------------------------- /packages/bs-loader/index.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | const {readBsConfig, readBsConfigSync} = require('read-bsconfig') 4 | const path = require('path') 5 | const {getOptions} = require('loader-utils') 6 | const {compileFile, compileFileSync} = require('bsb-js') 7 | const babel = require('@babel/core') 8 | /*:: import type { BsModuleFormat } from 'read-bsconfig' */ 9 | /*:: import type { WebpackLoaderThis } from 'webpack' */ 10 | 11 | const outputDir = 'lib' 12 | const fileNameRegex = /\.(ml|re)$/ 13 | 14 | function jsFilePath(buildDir, moduleDir, resourcePath, inSource, bsSuffix) { 15 | const mlFileName = resourcePath.replace(buildDir, '') 16 | const jsFileName = mlFileName.replace(fileNameRegex, bsSuffix) 17 | 18 | if (inSource) { 19 | return path.join(buildDir, jsFileName) 20 | } 21 | 22 | return path.join(buildDir, outputDir, moduleDir, jsFileName) 23 | } 24 | 25 | /*:: type Options = { moduleDir: BsModuleFormat | 'js', inSource: boolean, suffix: string } */ 26 | 27 | function bsconfigToOptions(bsconfig) /*: Options */ { 28 | const bsSuffix = bsconfig.suffix 29 | const suffix = typeof bsSuffix === 'string' ? bsSuffix : '.js' 30 | 31 | if (!bsconfig['package-specs']) { 32 | const options /*: Options */ = { 33 | moduleDir: 'js', 34 | inSource: false, 35 | suffix, 36 | } 37 | return options 38 | } 39 | 40 | const packageSpecs = bsconfig['package-specs'] 41 | const moduleSpec = 42 | packageSpecs instanceof Array ? packageSpecs[0] : packageSpecs 43 | const moduleDir /*: BsModuleFormat */ = 44 | typeof moduleSpec === 'string' ? moduleSpec : moduleSpec.module 45 | const inSource = 46 | typeof moduleSpec === 'string' ? false : moduleSpec['in-source'] 47 | 48 | const options /*: Options */ = {moduleDir, inSource, suffix} 49 | return options 50 | } 51 | 52 | function getBsConfigModuleOptions(buildDir) /*: Promise */ { 53 | return readBsConfig(buildDir).then(bsconfig => { 54 | if (!bsconfig) { 55 | throw new Error(`bsconfig not found in ${buildDir}`) 56 | } 57 | 58 | return bsconfigToOptions(bsconfig) 59 | }) 60 | } 61 | 62 | module.exports = function loader() { 63 | const options = getOptions(this) || {} 64 | const buildDir = options.cwd || process.cwd() 65 | const callback = this.async() 66 | const showWarnings = 67 | options.showWarnings !== undefined ? options.showWarnings : true 68 | 69 | this.addContextDependency(this.context) 70 | 71 | getBsConfigModuleOptions(buildDir) 72 | .then(bsconfig => { 73 | const moduleDir = bsconfig.moduleDir 74 | const bsSuffix = bsconfig.suffix 75 | 76 | const inSourceBuild = options.inSource || bsconfig.inSource || false 77 | 78 | const compiledFilePath = jsFilePath( 79 | buildDir, 80 | moduleDir, 81 | this.resourcePath, 82 | inSourceBuild, 83 | bsSuffix, 84 | ) 85 | 86 | return compileFile(buildDir, moduleDir, compiledFilePath) 87 | }) 88 | .then(({src, warnings, errors}) => { 89 | if (showWarnings) { 90 | warnings.forEach(message => { 91 | this.emitWarning(new Error(message)) 92 | }) 93 | } 94 | 95 | if (errors.length > 0) { 96 | for (let i = 0; i < errors.length - 1; ++i) { 97 | this.emitError(errors[i]) 98 | } 99 | 100 | callback(errors[errors.length - 1], null) 101 | } else { 102 | callback(null, src || '') 103 | } 104 | }) 105 | } 106 | 107 | /*:: declare var c: WebpackLoaderThis; module.exports.call(c) */ 108 | 109 | module.exports.process = function bsLoaderProcess( 110 | src /*: string */, 111 | filename /*: string */, 112 | curDirOrJestConfig /*: ?string | {rootDir: string} */, 113 | ) { 114 | // When this is used as Jest transform, we're passed an object that, among 115 | // other properties, has a `rootDir` key 116 | const cwd = curDirOrJestConfig != null ? 117 | (typeof curDirOrJestConfig === 'string' ? curDirOrJestConfig : curDirOrJestConfig.rootDir) 118 | : undefined 119 | const bsconfig = readBsConfigSync(cwd) 120 | const options = bsconfigToOptions(bsconfig) 121 | const inSourceBuild = options.inSource || false 122 | const bsSuffix = options.suffix 123 | const moduleDir = 'js' 124 | const compiledFilePath = jsFilePath( 125 | cwd || process.cwd(), 126 | moduleDir, 127 | filename, 128 | inSourceBuild, 129 | bsSuffix, 130 | ) 131 | 132 | const jsSource = compileFileSync( 133 | cwd || process.cwd(), 134 | moduleDir, 135 | compiledFilePath, 136 | ) 137 | 138 | const transformed = babel.transform(jsSource, { 139 | plugins: ['@babel/plugin-transform-modules-commonjs'], 140 | }) 141 | 142 | return transformed.code 143 | } 144 | -------------------------------------------------------------------------------- /packages/bs-loader/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bs-loader", 3 | "version": "2.0.7", 4 | "description": "Bucklescript integration in Webpack", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "jest" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/reasonml-community/bs-loader.git" 12 | }, 13 | "files": ["index.js"], 14 | "keywords": ["bucklescript", "reason", "webpack", "ocaml", "reasonml"], 15 | "author": "Ryan Delaney ", 16 | "license": "MIT", 17 | "bugs": { 18 | "url": "https://github.com/reasonml-community/reason-scripts/issues" 19 | }, 20 | "homepage": "https://github.com/reasonml-community/reason-scripts#readme", 21 | "dependencies": { 22 | "@babel/core": "7.1.0", 23 | "@babel/plugin-transform-modules-commonjs": "^7.1.0", 24 | "bsb-js": "^1.0.0", 25 | "loader-utils": "^1.1.0", 26 | "read-bsconfig": "^1.0.1" 27 | }, 28 | "devDependencies": { 29 | "jest": "^23.6.0", 30 | "webpack": "^3.12.0" 31 | }, 32 | "jest": { 33 | "testPathIgnorePatterns": ["/node_modules/", "/example/"] 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/bs-loader/test/insource/bsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "insource-test", 3 | "sources": ["fixtures"], 4 | "package-specs": [ 5 | { 6 | "module": "es6", 7 | "in-source": true 8 | } 9 | ], 10 | "refmt": 3 11 | } 12 | -------------------------------------------------------------------------------- /packages/bs-loader/test/insource/fixtures/add.js: -------------------------------------------------------------------------------- 1 | // Generated by BUCKLESCRIPT VERSION 4.0.5, PLEASE EDIT WITH CARE 2 | 3 | 4 | function add(x, y) { 5 | return x + y | 0; 6 | } 7 | 8 | export { 9 | add , 10 | 11 | } 12 | /* No side effect */ 13 | -------------------------------------------------------------------------------- /packages/bs-loader/test/insource/fixtures/add.re: -------------------------------------------------------------------------------- 1 | let add = (x, y) => x + y; 2 | -------------------------------------------------------------------------------- /packages/bs-loader/test/insource/fixtures/dec.js: -------------------------------------------------------------------------------- 1 | export const dec = x => x - 1; 2 | -------------------------------------------------------------------------------- /packages/bs-loader/test/insource/fixtures/fib.js: -------------------------------------------------------------------------------- 1 | // Generated by BUCKLESCRIPT VERSION 4.0.5, PLEASE EDIT WITH CARE 2 | 3 | import * as Add from "./add.js"; 4 | import * as Dec from "./dec"; 5 | 6 | function fib(n) { 7 | var _n = n; 8 | var _a = 1; 9 | var _b = 1; 10 | while(true) { 11 | var b = _b; 12 | var a = _a; 13 | var n$1 = _n; 14 | if (n$1 === 0) { 15 | return a; 16 | } else { 17 | _b = Add.add(a, b); 18 | _a = b; 19 | _n = Dec.dec(n$1); 20 | continue ; 21 | } 22 | }; 23 | } 24 | 25 | export { 26 | fib , 27 | 28 | } 29 | /* ./dec Not a pure module */ 30 | -------------------------------------------------------------------------------- /packages/bs-loader/test/insource/fixtures/fib.ml: -------------------------------------------------------------------------------- 1 | external dec : int -> int = "dec" [@@bs.module "./dec"] 2 | open Add 3 | 4 | let fib n = 5 | let rec aux n a b = 6 | if n = 0 then a 7 | else 8 | aux (dec n) b (add a b) 9 | in aux n 1 1 10 | -------------------------------------------------------------------------------- /packages/bs-loader/test/insource/fixtures/fib.mli: -------------------------------------------------------------------------------- 1 | val fib : int -> int 2 | -------------------------------------------------------------------------------- /packages/bs-loader/test/insource/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "insource-test", 3 | "private": true, 4 | "version": "100.0.0", 5 | "license": "MIT" 6 | } 7 | -------------------------------------------------------------------------------- /packages/bs-loader/test/insource/webpack.test.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack') 2 | const path = require('path') 3 | const fs = require('fs') 4 | 5 | try { 6 | require('child_process').execSync('npm link bs-platform') 7 | } catch (e) {} 8 | 9 | const output = path.join(__dirname, 'output', 'webpack') 10 | const loader = path.join(__dirname, '..', '..') 11 | 12 | const baseConfig = { 13 | entry: path.join(__dirname, 'fixtures/fib.ml'), 14 | module: { 15 | rules: [ 16 | { 17 | test: /\.(re|ml)$/, 18 | use: { 19 | loader, 20 | options: { 21 | module: 'es6', 22 | inSource: true, 23 | cwd: __dirname, 24 | }, 25 | }, 26 | }, 27 | ], 28 | }, 29 | resolve: { 30 | extensions: ['.re', '.ml', '.js'], 31 | }, 32 | output: { 33 | path: output, 34 | libraryTarget: 'commonjs2', 35 | }, 36 | } 37 | 38 | it('runs', done => { 39 | webpack(baseConfig, err => { 40 | expect(err).toBeNull() 41 | 42 | fs.readdir(output, (err, files) => { 43 | expect(err).toBeNull() 44 | expect(files.length).toBe(1) 45 | const result = require(path.resolve(output, files[0])) 46 | expect(result.fib(12)).toBe(233) 47 | 48 | done() 49 | }) 50 | }) 51 | }) 52 | -------------------------------------------------------------------------------- /packages/bs-loader/test/jest-esm/bsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "insource-test", 3 | "sources": ["fixtures"], 4 | "package-specs": [ 5 | { 6 | "module": "es6", 7 | "in-source": true 8 | } 9 | ], 10 | "refmt": 3 11 | } 12 | -------------------------------------------------------------------------------- /packages/bs-loader/test/jest-esm/fixtures/add.js: -------------------------------------------------------------------------------- 1 | // Generated by BUCKLESCRIPT VERSION 4.0.5, PLEASE EDIT WITH CARE 2 | 3 | 4 | function add(x, y) { 5 | return x + y | 0; 6 | } 7 | 8 | export { 9 | add , 10 | 11 | } 12 | /* No side effect */ 13 | -------------------------------------------------------------------------------- /packages/bs-loader/test/jest-esm/fixtures/add.re: -------------------------------------------------------------------------------- 1 | let add = (x, y) => x + y; 2 | -------------------------------------------------------------------------------- /packages/bs-loader/test/jest-esm/fixtures/adder.js: -------------------------------------------------------------------------------- 1 | // Generated by BUCKLESCRIPT VERSION 4.0.5, PLEASE EDIT WITH CARE 2 | 3 | import * as Add from "./add.js"; 4 | 5 | var result = Add.add(1, 4); 6 | 7 | export { 8 | result , 9 | 10 | } 11 | /* result Not a pure module */ 12 | -------------------------------------------------------------------------------- /packages/bs-loader/test/jest-esm/fixtures/adder.re: -------------------------------------------------------------------------------- 1 | let result = Add.add(1, 4); 2 | -------------------------------------------------------------------------------- /packages/bs-loader/test/jest-esm/fixtures/dec.js: -------------------------------------------------------------------------------- 1 | export const dec = x => x - 1; 2 | -------------------------------------------------------------------------------- /packages/bs-loader/test/jest-esm/fixtures/fib.js: -------------------------------------------------------------------------------- 1 | // Generated by BUCKLESCRIPT VERSION 4.0.5, PLEASE EDIT WITH CARE 2 | 3 | import * as Add from "./add.js"; 4 | import * as Dec from "./dec"; 5 | 6 | function fib(n) { 7 | var _n = n; 8 | var _a = 1; 9 | var _b = 1; 10 | while(true) { 11 | var b = _b; 12 | var a = _a; 13 | var n$1 = _n; 14 | if (n$1 === 0) { 15 | return a; 16 | } else { 17 | _b = Add.add(a, b); 18 | _a = b; 19 | _n = Dec.dec(n$1); 20 | continue ; 21 | } 22 | }; 23 | } 24 | 25 | export { 26 | fib , 27 | 28 | } 29 | /* ./dec Not a pure module */ 30 | -------------------------------------------------------------------------------- /packages/bs-loader/test/jest-esm/fixtures/fib.ml: -------------------------------------------------------------------------------- 1 | external dec : int -> int = "dec" [@@bs.module "./dec"] 2 | open Add 3 | 4 | let fib n = 5 | let rec aux n a b = 6 | if n = 0 then a 7 | else 8 | aux (dec n) b (add a b) 9 | in aux n 1 1 10 | -------------------------------------------------------------------------------- /packages/bs-loader/test/jest-esm/fixtures/fib.mli: -------------------------------------------------------------------------------- 1 | val fib : int -> int 2 | -------------------------------------------------------------------------------- /packages/bs-loader/test/jest-esm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jest-esm-test", 3 | "private": true, 4 | "version": "100.0.0", 5 | "license": "MIT" 6 | } 7 | -------------------------------------------------------------------------------- /packages/bs-loader/test/jest-esm/test.js: -------------------------------------------------------------------------------- 1 | const {process: processJest} = require('../../index.js') 2 | 3 | test('bs-loader compiles ES modules to CommonJS for Jest', () => { 4 | const jsSource = processJest('', './fixtures/adder.re', __dirname) 5 | 6 | const fakeAdd = jest.fn().mockImplementation((x, y) => x + y) 7 | const fakeRequire = jest.fn().mockImplementation(() => ({ 8 | add: fakeAdd, 9 | })) 10 | 11 | const oldRequire = require 12 | require = fakeRequire 13 | 14 | const evalSource = () => eval(jsSource) 15 | expect(evalSource).not.toThrow() 16 | expect(fakeRequire).toHaveBeenCalledWith('./add.js') 17 | expect(fakeAdd).toHaveBeenCalled() 18 | 19 | require = oldRequire 20 | }) 21 | -------------------------------------------------------------------------------- /packages/bs-loader/test/no-config/bsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "insource-test", 3 | "sources": ["fixtures"], 4 | "package-specs": [ 5 | { 6 | "module": "es6", 7 | "in-source": true 8 | } 9 | ], 10 | "refmt": 3 11 | } 12 | -------------------------------------------------------------------------------- /packages/bs-loader/test/no-config/fixtures/add.js: -------------------------------------------------------------------------------- 1 | // Generated by BUCKLESCRIPT VERSION 4.0.5, PLEASE EDIT WITH CARE 2 | 3 | 4 | function add(x, y) { 5 | return x + y | 0; 6 | } 7 | 8 | export { 9 | add , 10 | 11 | } 12 | /* No side effect */ 13 | -------------------------------------------------------------------------------- /packages/bs-loader/test/no-config/fixtures/add.re: -------------------------------------------------------------------------------- 1 | let add = (x, y) => x + y; 2 | -------------------------------------------------------------------------------- /packages/bs-loader/test/no-config/fixtures/dec.js: -------------------------------------------------------------------------------- 1 | export const dec = x => x - 1; 2 | -------------------------------------------------------------------------------- /packages/bs-loader/test/no-config/fixtures/fib.js: -------------------------------------------------------------------------------- 1 | // Generated by BUCKLESCRIPT VERSION 4.0.5, PLEASE EDIT WITH CARE 2 | 3 | import * as Add from "./add.js"; 4 | import * as Dec from "./dec"; 5 | 6 | function fib(n) { 7 | var _n = n; 8 | var _a = 1; 9 | var _b = 1; 10 | while(true) { 11 | var b = _b; 12 | var a = _a; 13 | var n$1 = _n; 14 | if (n$1 === 0) { 15 | return a; 16 | } else { 17 | _b = Add.add(a, b); 18 | _a = b; 19 | _n = Dec.dec(n$1); 20 | continue ; 21 | } 22 | }; 23 | } 24 | 25 | export { 26 | fib , 27 | 28 | } 29 | /* ./dec Not a pure module */ 30 | -------------------------------------------------------------------------------- /packages/bs-loader/test/no-config/fixtures/fib.ml: -------------------------------------------------------------------------------- 1 | external dec : int -> int = "dec" [@@bs.module "./dec"] 2 | open Add 3 | 4 | let fib n = 5 | let rec aux n a b = 6 | if n = 0 then a 7 | else 8 | aux (dec n) b (add a b) 9 | in aux n 1 1 10 | -------------------------------------------------------------------------------- /packages/bs-loader/test/no-config/fixtures/fib.mli: -------------------------------------------------------------------------------- 1 | val fib : int -> int 2 | -------------------------------------------------------------------------------- /packages/bs-loader/test/no-config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "no-config-test", 3 | "private": true, 4 | "version": "100.0.0", 5 | "license": "MIT" 6 | } 7 | -------------------------------------------------------------------------------- /packages/bs-loader/test/no-config/webpack.test.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack') 2 | const path = require('path') 3 | const fs = require('fs') 4 | 5 | try { 6 | require('child_process').execSync('npm link bs-platform') 7 | } catch (e) {} 8 | 9 | const output = path.join(__dirname, 'output', 'webpack') 10 | const loader = path.join(__dirname, '..', '..') 11 | 12 | const baseConfig = { 13 | entry: path.join(__dirname, 'fixtures/fib.ml'), 14 | module: { 15 | rules: [ 16 | { 17 | test: /\.(re|ml)$/, 18 | use: { 19 | loader, 20 | options: { 21 | cwd: __dirname, 22 | }, 23 | }, 24 | }, 25 | ], 26 | }, 27 | resolve: { 28 | extensions: ['.re', '.ml', '.js'], 29 | }, 30 | output: { 31 | path: output, 32 | libraryTarget: 'commonjs2', 33 | }, 34 | } 35 | 36 | it('runs', done => { 37 | webpack(baseConfig, err => { 38 | expect(err).toBeNull() 39 | 40 | fs.readdir(output, (err, files) => { 41 | expect(err).toBeNull() 42 | expect(files.length).toBe(1) 43 | const result = require(path.resolve(output, files[0])) 44 | expect(result.fib(12)).toBe(233) 45 | 46 | done() 47 | }) 48 | }) 49 | }) 50 | -------------------------------------------------------------------------------- /packages/bs-loader/test/simple/bsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simple-test", 3 | "sources": ["fixtures"], 4 | "package-specs": ["es6"], 5 | "refmt": 3 6 | } 7 | -------------------------------------------------------------------------------- /packages/bs-loader/test/simple/fixtures/add.js: -------------------------------------------------------------------------------- 1 | // Generated by BUCKLESCRIPT VERSION 1.9.1, PLEASE EDIT WITH CARE 2 | 'use strict'; 3 | 4 | 5 | function add(x, y) { 6 | return x + y | 0; 7 | } 8 | 9 | export { 10 | add , 11 | 12 | } 13 | /* No side effect */ 14 | -------------------------------------------------------------------------------- /packages/bs-loader/test/simple/fixtures/add.re: -------------------------------------------------------------------------------- 1 | let add = (x, y) => x + y; 2 | -------------------------------------------------------------------------------- /packages/bs-loader/test/simple/fixtures/dec.js: -------------------------------------------------------------------------------- 1 | export const dec = x => x - 1; 2 | -------------------------------------------------------------------------------- /packages/bs-loader/test/simple/fixtures/fib.js: -------------------------------------------------------------------------------- 1 | // Generated by BUCKLESCRIPT VERSION 1.9.1, PLEASE EDIT WITH CARE 2 | 'use strict'; 3 | 4 | import * as Add from "./add.js"; 5 | import * as $dot$slashdec from "./dec"; 6 | 7 | function fib(n) { 8 | var _n = n; 9 | var _a = 1; 10 | var _b = 1; 11 | while(true) { 12 | var b = _b; 13 | var a = _a; 14 | var n$1 = _n; 15 | if (n$1) { 16 | _b = Add.add(a, b); 17 | _a = b; 18 | _n = $dot$slashdec.dec(n$1); 19 | continue ; 20 | 21 | } else { 22 | return a; 23 | } 24 | }; 25 | } 26 | 27 | export { 28 | fib , 29 | 30 | } 31 | /* ./dec Not a pure module */ 32 | -------------------------------------------------------------------------------- /packages/bs-loader/test/simple/fixtures/fib.ml: -------------------------------------------------------------------------------- 1 | external dec : int -> int = "dec" [@@bs.module "./dec"] 2 | open Add 3 | 4 | let fib n = 5 | let rec aux n a b = 6 | if n = 0 then a 7 | else 8 | aux (dec n) b (add a b) 9 | in aux n 1 1 10 | -------------------------------------------------------------------------------- /packages/bs-loader/test/simple/fixtures/fib.mli: -------------------------------------------------------------------------------- 1 | val fib : int -> int 2 | -------------------------------------------------------------------------------- /packages/bs-loader/test/simple/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simple-test", 3 | "private": true, 4 | "version": "100.0.0", 5 | "license": "MIT" 6 | } 7 | -------------------------------------------------------------------------------- /packages/bs-loader/test/simple/webpack.test.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack') 2 | const path = require('path') 3 | const fs = require('fs') 4 | 5 | try { 6 | require('child_process').execSync('npm link bs-platform') 7 | } catch (e) {} 8 | 9 | const output = path.join(__dirname, 'output', 'webpack') 10 | const loader = path.join(__dirname, '..', '..') 11 | 12 | const baseConfig = { 13 | entry: path.join(__dirname, 'fixtures/fib.ml'), 14 | module: { 15 | rules: [ 16 | { 17 | test: /\.(re|ml)$/, 18 | use: { 19 | loader, 20 | options: { 21 | cwd: __dirname, 22 | }, 23 | }, 24 | }, 25 | ], 26 | }, 27 | resolve: { 28 | extensions: ['.re', '.ml', '.js'], 29 | }, 30 | output: { 31 | path: output, 32 | libraryTarget: 'commonjs2', 33 | }, 34 | } 35 | 36 | it('runs', done => { 37 | webpack(baseConfig, err => { 38 | expect(err).toBeNull() 39 | 40 | fs.readdir(output, (err, files) => { 41 | expect(err).toBeNull() 42 | expect(files.length).toBe(1) 43 | const result = require(path.resolve(output, files[0])) 44 | expect(result.fib(12)).toBe(233) 45 | 46 | done() 47 | }) 48 | }) 49 | }) 50 | -------------------------------------------------------------------------------- /packages/bs-loader/test/warnings-super/bsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "warnings-super-test", 3 | "sources": ["fixtures"], 4 | "package-specs": ["es6"], 5 | "bsc-flags": ["-bs-super-errors"], 6 | "refmt": 3 7 | } 8 | -------------------------------------------------------------------------------- /packages/bs-loader/test/warnings-super/fixtures/index.re: -------------------------------------------------------------------------------- 1 | type a = 2 | | One 3 | | Two; 4 | 5 | switch One { 6 | | One => "One" 7 | }; 8 | -------------------------------------------------------------------------------- /packages/bs-loader/test/warnings-super/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "warnings-super-test", 3 | "private": true, 4 | "version": "100.0.0", 5 | "license": "MIT" 6 | } 7 | -------------------------------------------------------------------------------- /packages/bs-loader/test/warnings-super/webpack.test.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack') 2 | const path = require('path') 3 | const fs = require('fs') 4 | const os = require('os') 5 | const {exec} = require('child_process') 6 | 7 | try { 8 | require('child_process').execSync('npm link bs-platform') 9 | } catch (e) {} 10 | 11 | const output = path.join(__dirname, 'output', 'webpack') 12 | const loader = path.join(__dirname, '..', '..') 13 | 14 | const baseConfig = { 15 | entry: path.join(__dirname, 'fixtures/index.re'), 16 | module: { 17 | rules: [ 18 | { 19 | test: /\.(re|ml)$/, 20 | use: { 21 | loader, 22 | options: { 23 | cwd: __dirname, 24 | }, 25 | }, 26 | }, 27 | ], 28 | }, 29 | resolve: { 30 | extensions: ['.re', '.ml', '.js'], 31 | }, 32 | output: { 33 | path: output, 34 | libraryTarget: 'commonjs2', 35 | }, 36 | } 37 | 38 | let bsbCommand 39 | try { 40 | bsbCommand = require.resolve('bs-platform/bin/bsb.exe') 41 | } catch (e) { 42 | bsbCommand = `bsb` 43 | } 44 | 45 | const bsb = 46 | os.platform() === 'darwin' 47 | ? `script -q /dev/null ${bsbCommand} -clean-world` 48 | : os.platform() === 'linux' 49 | ? `script --return -qfc "${bsbCommand} -clean-world" /dev/null` 50 | : `${bsbCommand} -clean-world` 51 | 52 | it('runs', done => { 53 | exec(bsb, {maxBuffer: Infinity, cwd: __dirname}, (err, stdout, stderr) => { 54 | if (err) { 55 | done(err) 56 | return 57 | } 58 | 59 | webpack(baseConfig, (err, stats) => { 60 | expect(err).toBeNull() 61 | expect(stats.toJson().warnings.length).toBe(1) 62 | 63 | done() 64 | }) 65 | }) 66 | }) 67 | -------------------------------------------------------------------------------- /packages/bs-loader/test/warnings/bsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "warnings-test", 3 | "sources": ["fixtures"], 4 | "package-specs": ["es6"], 5 | "refmt": 3 6 | } 7 | -------------------------------------------------------------------------------- /packages/bs-loader/test/warnings/fixtures/index.re: -------------------------------------------------------------------------------- 1 | type a = 2 | | One 3 | | Two; 4 | 5 | switch One { 6 | | One => "One" 7 | }; 8 | -------------------------------------------------------------------------------- /packages/bs-loader/test/warnings/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "warnings-test", 3 | "private": true, 4 | "version": "100.0.0", 5 | "license": "MIT" 6 | } 7 | -------------------------------------------------------------------------------- /packages/bs-loader/test/warnings/webpack.test.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack') 2 | const path = require('path') 3 | const fs = require('fs') 4 | const os = require('os') 5 | const {exec} = require('child_process') 6 | 7 | try { 8 | require('child_process').execSync('npm link bs-platform') 9 | } catch (e) {} 10 | 11 | const output = path.join(__dirname, 'output', 'webpack') 12 | const loader = path.join(__dirname, '..', '..') 13 | 14 | const baseConfig = { 15 | entry: path.join(__dirname, 'fixtures/index.re'), 16 | module: { 17 | rules: [ 18 | { 19 | test: /\.(re|ml)$/, 20 | use: { 21 | loader, 22 | options: { 23 | cwd: __dirname, 24 | }, 25 | }, 26 | }, 27 | ], 28 | }, 29 | resolve: { 30 | extensions: ['.re', '.ml', '.js'], 31 | }, 32 | output: { 33 | path: output, 34 | libraryTarget: 'commonjs2', 35 | }, 36 | } 37 | 38 | let bsbCommand 39 | try { 40 | bsbCommand = require.resolve('bs-platform/bin/bsb.exe') 41 | } catch (e) { 42 | bsbCommand = `bsb` 43 | } 44 | 45 | const bsb = 46 | os.platform() === 'darwin' 47 | ? `script -q /dev/null ${bsbCommand} -clean-world` 48 | : os.platform() === 'linux' 49 | ? `script --return -qfc "${bsbCommand} -clean-world" /dev/null` 50 | : `${bsbCommand} -clean-world` 51 | 52 | it('runs', done => { 53 | exec(bsb, {maxBuffer: Infinity, cwd: __dirname}, (err, stdout, stderr) => { 54 | if (err) { 55 | done(err) 56 | return 57 | } 58 | 59 | webpack(baseConfig, (err, stats) => { 60 | expect(err).toBeNull() 61 | expect(stats.toJson().warnings.length).toBe(1) 62 | 63 | done() 64 | }) 65 | }) 66 | }) 67 | -------------------------------------------------------------------------------- /packages/bsb-js/.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | node_modules 3 | -------------------------------------------------------------------------------- /packages/bsb-js/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Ryan Delaney 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/bsb-js/README.md: -------------------------------------------------------------------------------- 1 | # bsb-js 2 | 3 | > JS library wrapping BuckleScript build 4 | -------------------------------------------------------------------------------- /packages/bsb-js/index.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | const os = require('os') 4 | const {exec, execSync} = require('child_process') 5 | const {readFile, readFileSync} = require('fs') 6 | const utils = require('./utils') 7 | /*:: import type { BsModuleFormat } from 'read-bsconfig' */ 8 | 9 | let bsbCommand 10 | try { 11 | bsbCommand = require.resolve('bs-platform/lib/bsb.exe') 12 | } catch (e) { 13 | bsbCommand = `bsb` 14 | } 15 | 16 | const bsb = (() => { 17 | switch (utils.platform()) { 18 | case 'darwin': 19 | return `script -q /dev/null ${bsbCommand} -make-world` 20 | case 'linux': 21 | return `script --return -qfc "${bsbCommand} -make-world" /dev/null` 22 | case 'wsl': 23 | return `${bsbCommand} -make-world` 24 | default: 25 | return `${bsbCommand} -make-world` 26 | } 27 | })() 28 | 29 | /** Runs `bsb` async */ 30 | function runBuild(cwd /*: string */) /*: Promise */ { 31 | return new Promise((resolve, reject) => { 32 | exec(bsb, {maxBuffer: Infinity, cwd}, (err, stdout, stderr) => { 33 | const output = `${stdout.toString()}\n${stderr.toString()}` 34 | if (err) { 35 | reject(output) 36 | } else { 37 | resolve(output) 38 | } 39 | }) 40 | }) 41 | } 42 | 43 | /** Runs `bsb` */ 44 | function runBuildSync(cwd /*: string */) /*: string */ { 45 | const output = execSync(bsb, {stdio: 'pipe', cwd}) 46 | 47 | return output.toString() 48 | } 49 | 50 | /*:: 51 | type Compilation = { 52 | src: ?string, 53 | warnings: string[], 54 | errors: Array 55 | } 56 | */ 57 | 58 | const buildRuns /*: { [buildId: string]: Promise } */ = {} 59 | 60 | /** Compiles a Reason file to JS */ 61 | function compileFile( 62 | buildDir /*: string */, 63 | moduleType /*: BsModuleFormat | 'js' */, 64 | path /*: string */, 65 | id /*: ?string */ = null, 66 | ) /*: Promise */ { 67 | if (id && buildRuns[id] !== undefined) { 68 | buildRuns[id] = runBuild(buildDir) 69 | } 70 | 71 | const buildProcess = id ? buildRuns[id] : runBuild(buildDir) 72 | 73 | return buildProcess 74 | .then( 75 | output => 76 | new Promise((resolve, reject) => { 77 | readFile(path, (err, res) => { 78 | if (err) { 79 | resolve({ 80 | src: undefined, 81 | warnings: [], 82 | errors: [err], 83 | }) 84 | } else { 85 | const src = utils.transformSrc(moduleType, res.toString()) 86 | 87 | resolve({ 88 | src, 89 | warnings: utils.processBsbWarnings(output), 90 | errors: [], 91 | }) 92 | } 93 | }) 94 | }), 95 | ) 96 | .catch(err => ({ 97 | src: undefined, 98 | warnings: [], 99 | errors: utils.processBsbError(err), 100 | })) 101 | } 102 | 103 | /** Compiles a Reason file to JS sync */ 104 | function compileFileSync( 105 | buildDir /*: string */, 106 | moduleType /*: BsModuleFormat | 'js' */, 107 | path /*: string */, 108 | ) /*: string */ { 109 | try { 110 | runBuildSync(buildDir) 111 | } catch (e) { 112 | throw utils.processBsbError(e.output.toString()) 113 | } 114 | 115 | const res = readFileSync(path) 116 | return utils.transformSrc(moduleType, res.toString()) 117 | } 118 | 119 | module.exports = { 120 | BSB: bsb, 121 | runBuild, 122 | runBuildSync, 123 | compileFile, 124 | compileFileSync, 125 | } 126 | -------------------------------------------------------------------------------- /packages/bsb-js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bsb-js", 3 | "version": "1.1.7", 4 | "description": "JS library wrapping BuckleScript build", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "jest" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/reasonml-community/bs-loader.git" 12 | }, 13 | "keywords": [ 14 | "bsb", 15 | "bucklescript", 16 | "reason", 17 | "reasonml" 18 | ], 19 | "author": "Ryan Delaney ", 20 | "license": "MIT", 21 | "bugs": { 22 | "url": "https://github.com/reasonml-community/reason-scripts/issues" 23 | }, 24 | "homepage": "https://github.com/reasonml-community/reason-scripts#readme" 25 | } 26 | -------------------------------------------------------------------------------- /packages/bsb-js/utils.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | const os = require('os') 4 | /*:: import type { BsModuleFormat } from 'read-bsconfig' */ 5 | 6 | const fileNameRegex = /\.(ml|re)$/ 7 | const es6ReplaceRegex = /(from\ "\.\.?\/.*?)(\.bs\.js|\.js)("\;)/g 8 | const commonJsReplaceRegex = /(require\("\.\.?\/.*?)(\.bs\.js|\.js)("\);)/g 9 | const getErrorRegex = /(File [\s\S]*?:\r?\n|Fatal )[eE]rror: [\s\S]*?(?=ninja|\r?\n\r?\n|$)/g 10 | const packageNotFoundRegex = /Package not found[\s\S]*?:?\r?\n[\s\S]*?[eE]rror:\s?[\s\S]*/g 11 | const getSuperErrorRegex = /We've found a bug for you![\s\S]*?(?=ninja: build stopped)/g 12 | const getWarningRegex = /((File [\s\S]*?Warning.+? \d+:)|Warning number \d+)[\s\S]*?(?=\[\d+\/\d+\]|$)/g 13 | const errorRegexes = [getSuperErrorRegex, getErrorRegex, packageNotFoundRegex] 14 | 15 | function platform() /*: 'darwin' | 'linux' | 'wsl' | null */ { 16 | const isWSL = () => { 17 | const release = os.release() 18 | return ( 19 | release.substring(release.length - 'Microsoft'.length) === 'Microsoft' 20 | ) 21 | } 22 | 23 | if (os.platform() === 'darwin') return 'darwin' 24 | if (os.platform() === 'linux' && isWSL()) return 'wsl' 25 | if (os.platform() === 'linux') return 'linux' 26 | return null 27 | } 28 | 29 | function transformSrc( 30 | moduleType /*: BsModuleFormat | 'js' */, 31 | src /*: string */, 32 | ) { 33 | const replacer = moduleType === 'es6' ? es6ReplaceRegex : commonJsReplaceRegex 34 | 35 | return src.replace(replacer, '$1$3') 36 | } 37 | 38 | // This function is only ever called if an error has been caught. We try to 39 | // process said error according to known formats, but we default to what we 40 | // got as an argument if they don't match. This way we always throw an error, 41 | // thus avoiding successful builds if something has gone wrong. 42 | function processBsbError(err /*: Error | string */) /*: Error[] */ { 43 | if (typeof err === 'string') { 44 | const errors = errorRegexes 45 | // $FlowIssue: err is definitely a string 46 | .map((r /*: RegExp */) => err.match(r)) 47 | .reduce((a, s) => a.concat(s), []) 48 | .filter(x => x) 49 | 50 | return (errors.length > 0 ? errors : [err]).map(e => new Error(e)) 51 | } else { 52 | return [err] 53 | } 54 | } 55 | 56 | function processBsbWarnings(output /*: string */) { 57 | return output.match(getWarningRegex) || [] 58 | } 59 | 60 | module.exports = { 61 | platform, 62 | transformSrc, 63 | processBsbError, 64 | processBsbWarnings, 65 | } 66 | -------------------------------------------------------------------------------- /packages/read-bsconfig/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | -------------------------------------------------------------------------------- /packages/read-bsconfig/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Ryan Delaney 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/read-bsconfig/README.md: -------------------------------------------------------------------------------- 1 | # read-bsconfig 2 | 3 | Library for reading the bsconfig.json for BuckleScript 4 | 5 | ## Usage 6 | 7 | ```js 8 | const { readBsConfig, readBsConfigSync } = require('read-bsconfig') 9 | 10 | // Read from the CWD 11 | const myConf = readBsConfig() 12 | 13 | // If the bsconfig is located somewhere else, pass it in as an arg 14 | const otherConf = readBsConfig(__dirname) 15 | 16 | // A bsconfig for a given path will be cached. This can be turned off 17 | // by passing a second parameter as false 18 | const notCachedConf = readBsConfig(__dirname, false) 19 | 20 | // You can also read a config sync 21 | // It has a the same arguments 22 | const mySyncConf = readBsConfigSync() 23 | ``` 24 | -------------------------------------------------------------------------------- /packages/read-bsconfig/__tests__/bsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | /* this is a comment */ 3 | "name": "reason-scripts", 4 | "sources": ["src"], 5 | "bs-dependencies": ["reason-react", "bs-jest"], 6 | "reason": { 7 | "react-jsx": 2 8 | }, 9 | "bsc-flags": ["-bs-super-errors"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/read-bsconfig/__tests__/read.js: -------------------------------------------------------------------------------- 1 | const { readBsConfig, readBsConfigSync } = require('../') 2 | 3 | test('Read bsconfig from process.cwd()', () => { 4 | expect(readBsConfig()).rejects.toBeDefined() 5 | expect() 6 | }) 7 | 8 | test('Read bsconfig from __dirname', async () => { 9 | const bsConfig = await readBsConfig(__dirname) 10 | 11 | expect(bsConfig).toEqual({ 12 | name: 'reason-scripts', 13 | sources: ['src'], 14 | 'bs-dependencies': ['reason-react', 'bs-jest'], 15 | reason: { 16 | 'react-jsx': 2 17 | }, 18 | 'bsc-flags': ['-bs-super-errors'] 19 | }) 20 | }) 21 | 22 | test('Read bsconfig from __dirname synchronously', () => { 23 | const bsConfig = readBsConfigSync(__dirname) 24 | 25 | expect(bsConfig).toEqual({ 26 | name: 'reason-scripts', 27 | sources: ['src'], 28 | 'bs-dependencies': ['reason-react', 'bs-jest'], 29 | reason: { 30 | 'react-jsx': 2 31 | }, 32 | 'bsc-flags': ['-bs-super-errors'] 33 | }) 34 | }) 35 | 36 | test('Cache should return same object for async reads', () => { 37 | let bs1 = readBsConfig(__dirname) 38 | let bs2 = readBsConfig(__dirname) 39 | 40 | expect(bs1).toBe(bs2) 41 | }) 42 | 43 | test('Cache should return same rejected promise', () => { 44 | let bs1 = readBsConfig() 45 | let bs2 = readBsConfig() 46 | 47 | expect(bs1).toBe(bs2) 48 | }) 49 | 50 | test('Cache can be disabled for async reads', () => { 51 | let bs1 = readBsConfig(__dirname, false) 52 | let bs2 = readBsConfig(__dirname, false) 53 | 54 | expect(bs1).not.toBe(bs2) 55 | }) 56 | 57 | test('Cache should return same object for sync reads', () => { 58 | let bs1 = readBsConfigSync(__dirname) 59 | let bs2 = readBsConfigSync(__dirname) 60 | 61 | expect(bs1).toBe(bs2) 62 | }) 63 | 64 | test('Cache can be disabled for sync reads', () => { 65 | let bs1 = readBsConfigSync(__dirname, false) 66 | let bs2 = readBsConfigSync(__dirname, false) 67 | 68 | expect(bs1).not.toBe(bs2) 69 | }) 70 | -------------------------------------------------------------------------------- /packages/read-bsconfig/index.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | /*:: 4 | export type BsDependency = string 5 | 6 | export type BsRuleGenerator = { 7 | name: string, 8 | command: string 9 | } 10 | 11 | export type BsJsxVersion = boolean | number 12 | 13 | export type BsReasonSpecs = { 14 | 'react-jsx': BsJsxVersion 15 | } 16 | 17 | export type BsJsPostBuild = { 18 | cmd: string 19 | } 20 | 21 | export type BsModuleFormat = 22 | | 'commonjs' 23 | | 'amdjs' 24 | | 'amdjs-global' 25 | | 'es6' 26 | | 'es6-global' 27 | 28 | export type BsPackageSpec = 29 | | BsModuleFormat 30 | | { module: BsModuleFormat, 'in-source': boolean } 31 | 32 | export type BsConfig = { 33 | version: string, 34 | name: string, 35 | namespace: boolean, 36 | sources: any, // TODO: fill in this definition 37 | 'bs-dependencies': BsDependency[], 38 | 'bs-dev-dependencies': BsDependency[], 39 | generators: BsRuleGenerator[], 40 | 'cut-generators': boolean, 41 | reason: BsReasonSpecs, 42 | 'bsc-flags': string[], 43 | 'ppx-flags': string[], 44 | 'js-post-build': BsJsPostBuild, 45 | 'package-specs': BsPackageSpec|BsPackageSpec[], 46 | ocamllex: string, 47 | ocamlyacc: string, 48 | menhir: string, 49 | entries: any, // TODO: fill in this definition 50 | 'generate-merlin': boolean, 51 | 'use-stdlib': boolean, 52 | 'bs-external-includes': string[], 53 | refmt: string, 54 | 'refmt-flags': string[], 55 | suffix: string 56 | } 57 | */ 58 | 59 | const { readFile, readFileSync } = require('fs') 60 | const path = require('path') 61 | const JSON5 = require('json5') 62 | 63 | let asyncConfigCache = {} 64 | 65 | function readBsConfig( 66 | cwd /*: string */ = process.cwd(), 67 | enableCache /*: boolean */ = true 68 | ) /*: Promise */ { 69 | if (asyncConfigCache[cwd] && enableCache) return asyncConfigCache[cwd] 70 | 71 | asyncConfigCache[cwd] = new Promise((resolve, reject) => { 72 | readFile(path.join(cwd, 'bsconfig.json'), (err, res) => { 73 | if (err) return reject(err) 74 | 75 | resolve(JSON5.parse(res.toString())) 76 | }) 77 | }) 78 | 79 | return asyncConfigCache[cwd] 80 | } 81 | 82 | let syncConfigCache = {} 83 | 84 | function readBsConfigSync( 85 | cwd /*: string */ = process.cwd(), 86 | enableCache /*: boolean */ = true 87 | ) /*: BsConfig */ { 88 | if (syncConfigCache[cwd] && enableCache) return syncConfigCache[cwd] 89 | 90 | const content = readFileSync(path.join(cwd, 'bsconfig.json')) 91 | syncConfigCache[cwd] = JSON5.parse(content.toString()) 92 | 93 | return syncConfigCache[cwd] 94 | } 95 | 96 | function clearCache() { 97 | asyncConfigCache = {} 98 | syncConfigCache = {} 99 | } 100 | 101 | module.exports = { readBsConfig, readBsConfigSync, clearCache } 102 | -------------------------------------------------------------------------------- /packages/read-bsconfig/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "read-bsconfig", 3 | "version": "1.0.5", 4 | "description": "Library for reading the bsconfig.json for BuckleScript", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "jest" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/reasonml-community/bs-loader.git" 12 | }, 13 | "author": "Ryan Delaney ", 14 | "license": "MIT", 15 | "bugs": { 16 | "url": "https://github.com/reasonml-community/reason-scripts/issues" 17 | }, 18 | "homepage": "https://github.com/reasonml-community/reason-scripts#readme", 19 | "dependencies": { 20 | "json5": "^0.5.1" 21 | }, 22 | "files": [ 23 | "index.js" 24 | ], 25 | "devDependencies": { 26 | "jest": "^21.0.1" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/reason-types-webpack-plugin/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | -------------------------------------------------------------------------------- /packages/reason-types-webpack-plugin/.npmignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | example 61 | -------------------------------------------------------------------------------- /packages/reason-types-webpack-plugin/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Ryan Delaney 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/reason-types-webpack-plugin/README.md: -------------------------------------------------------------------------------- 1 | # reason-types-webpack-plugin 2 | 3 | > `yarn add --dev reason-webpack-plugin` 4 | 5 | ### Installation 6 | 7 | Add the plugin to your webpack config 8 | 9 | ```js 10 | // webpack.config.js 11 | const ReasonTypesPlugin = require('reason-types-webpack-plugin') 12 | 13 | module.exports = { 14 | // ... 15 | plugins: [ 16 | new ReasonTypesPlugin({ sources: 'src' }) 17 | ] 18 | } 19 | ``` 20 | 21 | ReasonTypesPlugin will generate `.js.flow` files for you 22 | 23 | ```js 24 | // @flow 25 | 26 | import { add } from './my_reason_file' 27 | 28 | // The `add` function is typed! 29 | const value = add(100, 200) 30 | ``` 31 | -------------------------------------------------------------------------------- /packages/reason-types-webpack-plugin/example/.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | .*/node_modules/bs-platform/.* 3 | [include] 4 | src 5 | 6 | [libs] 7 | 8 | [options] 9 | -------------------------------------------------------------------------------- /packages/reason-types-webpack-plugin/example/.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | node_modules 3 | *.log 4 | lib 5 | types 6 | build 7 | src/**/*.js.flow 8 | -------------------------------------------------------------------------------- /packages/reason-types-webpack-plugin/example/.merlin: -------------------------------------------------------------------------------- 1 | ####{BSB GENERATED: NO EDIT 2 | FLG -ppx '/usr/local/lib/node_modules/bs-platform/bin/reactjs_jsx_ppx.exe' 3 | FLG -ppx /usr/local/lib/node_modules/bs-platform/bin/bsppx.exe 4 | S /Users/ryan/Documents/dev/reason-webpack-plugin/example/node_modules/bs-platform/lib/ocaml 5 | B /Users/ryan/Documents/dev/reason-webpack-plugin/example/node_modules/bs-platform/lib/ocaml 6 | FLG -nostdlib -no-alias-deps -color always -w -40+6+7+27+32..39+44+45 7 | S src 8 | B lib/bs/src 9 | S types 10 | B lib/bs/types 11 | ####BSB GENERATED: NO EDIT} 12 | -------------------------------------------------------------------------------- /packages/reason-types-webpack-plugin/example/bsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "sources": ["types", "src"], 4 | "bs-dependencies": [], 5 | "reason": { 6 | "react-jsx": true 7 | }, 8 | "package-specs": ["es6"], 9 | "bsc-flags": ["-bs-super-errors", "-bs-gen-tds"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/reason-types-webpack-plugin/example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "version": "1.0.0", 4 | "private": true, 5 | "description": "", 6 | "main": "webpack.config.js", 7 | "scripts": { 8 | "build": "webpack", 9 | "flow": "flow" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "babel-loader": "^7.0.0", 16 | "babel-preset-react-app": "^3.0.0", 17 | "bs-loader": "^1.6.0", 18 | "bs-platform": "^1.7.4", 19 | "flow-bin": "^0.54.0", 20 | "get-typed": "^1.0.0-beta.2", 21 | "webpack": "^3.5.5" 22 | }, 23 | "dependencies": { 24 | "reasonable-flowgen": "^0.1.5" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/reason-types-webpack-plugin/example/src/index.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import { print } from './print_math' 4 | 5 | export default function add(x: number, y: number): number { 6 | return x + y 7 | } 8 | 9 | print(200, 400) 10 | -------------------------------------------------------------------------------- /packages/reason-types-webpack-plugin/example/src/math.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | export function sub(x: number, y: number): number { 4 | return x - y 5 | } 6 | -------------------------------------------------------------------------------- /packages/reason-types-webpack-plugin/example/src/print_math.re: -------------------------------------------------------------------------------- 1 | let print x z => Js.log (Math.sub x z); 2 | -------------------------------------------------------------------------------- /packages/reason-types-webpack-plugin/example/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const ReasonPlugin = require('../') 3 | 4 | process.env.BABEL_ENV = 'development' 5 | 6 | module.exports = { 7 | entry: './src/index.js', 8 | output: { 9 | filename: 'out.js', 10 | path: path.join(__dirname, 'build') 11 | }, 12 | module: { 13 | rules: [ 14 | { 15 | test: /\.js$/, 16 | exclude: /node_modules/, 17 | use: { 18 | loader: 'babel-loader', 19 | options: { 20 | presets: ['react-app'] 21 | } 22 | } 23 | }, 24 | { 25 | test: /\.(re|ml)$/, 26 | use: [ 27 | { 28 | loader: 'bs-loader', 29 | options: { 30 | module: 'es6' 31 | } 32 | } 33 | ] 34 | } 35 | ] 36 | }, 37 | resolve: { 38 | extensions: ['.js', '.json', '.re'] 39 | }, 40 | plugins: [ 41 | new ReasonPlugin({ 42 | sources: 'src', 43 | output: 'types' 44 | }) 45 | ] 46 | } 47 | -------------------------------------------------------------------------------- /packages/reason-types-webpack-plugin/index.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | const { readFile, writeFile } = require('fs') 4 | const path = require('path') 5 | const glob = require('glob') 6 | const { default: flowgen } = require('reasonable-flowgen') 7 | /*:: import type { WebpackCompilerInstance } from 'webpack' */ 8 | 9 | const getDts = (context, file) => { 10 | const dtsFile = path.join(context, 'lib', 'bs', file.replace('.re', '.d.ts')) 11 | 12 | return new Promise((resolve, reject) => { 13 | readFile(dtsFile, (err, contents) => { 14 | if (err) return reject(err) 15 | 16 | resolve(contents.toString()) 17 | }) 18 | }) 19 | } 20 | 21 | const genFlowTypes = context => async chunkName => { 22 | try { 23 | const dtsSource = await getDts(context, chunkName) 24 | const flowSource = 25 | '// @flow\n\n' + flowgen.compileDefinitionString(dtsSource) 26 | const outputFile = path.join(context, chunkName.replace('.re', '.js.flow')) 27 | await new Promise((resolve, reject) => { 28 | writeFile(outputFile, flowSource, err => { 29 | if (err) return reject(err) 30 | 31 | resolve() 32 | }) 33 | }) 34 | } catch (e) {} 35 | } 36 | 37 | /*:: 38 | type PluginOptions = { 39 | sources: string 40 | } 41 | */ 42 | 43 | class ReasonTypesPlugin { 44 | /*:: sources: string */ 45 | 46 | constructor({ sources } /*: PluginOptions */) { 47 | this.sources = sources 48 | } 49 | 50 | apply(compiler /*: WebpackCompilerInstance */) { 51 | compiler.plugin('emit', async (compilation, cb) => { 52 | const baseDir = path.join(compiler.context, this.sources) 53 | 54 | const reFiles = await new Promise((resolve, reject) => 55 | glob(`${baseDir}/*.re`, (err, matches) => { 56 | if (err) return reject(err) 57 | resolve(matches) 58 | }) 59 | ) 60 | 61 | const relativeReFiles = reFiles.map(f => 62 | path.relative(compiler.context, f) 63 | ) 64 | 65 | await Promise.all(relativeReFiles.map(genFlowTypes(compiler.context))) 66 | 67 | cb() 68 | }) 69 | } 70 | } 71 | 72 | module.exports = ReasonTypesPlugin 73 | -------------------------------------------------------------------------------- /packages/reason-types-webpack-plugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reason-types-webpack-plugin", 3 | "version": "1.0.0", 4 | "description": "Webpack plugin for generating types for ReasonML", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/reasonml-community/bs-loader" 12 | }, 13 | "keywords": [ 14 | "webpack", 15 | "get-typed", 16 | "reason", 17 | "reasonml", 18 | "bucklescript" 19 | ], 20 | "author": "Ryan Delaney ", 21 | "license": "MIT", 22 | "bugs": { 23 | "url": "https://github.com/reasonml-community/bs-loader/issues" 24 | }, 25 | "homepage": "https://github.com/reasonml-community/bs-loader", 26 | "dependencies": { 27 | "glob": "^7.1.2", 28 | "reasonable-flowgen": "^0.1.5" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/reason-webpack-plugin/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | -------------------------------------------------------------------------------- /packages/reason-webpack-plugin/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Ryan Delaney 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/reason-webpack-plugin/README.md: -------------------------------------------------------------------------------- 1 | # reason-webpack-plugin 2 | 3 | > A webpack plugin to automatically compile Reason before compilation 4 | 5 | ### Usage 6 | 7 | ```js 8 | // webpack.config.js 9 | const ReasonPlugin = require('reason-webpack-plugin') 10 | 11 | module.exports = { 12 | // ... 13 | plugins: [ 14 | // ... 15 | new ReasonPlugin() 16 | ] 17 | } 18 | ``` 19 | -------------------------------------------------------------------------------- /packages/reason-webpack-plugin/example/.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | node_modules 3 | *.log 4 | lib 5 | types 6 | build 7 | *.bs.js 8 | -------------------------------------------------------------------------------- /packages/reason-webpack-plugin/example/.merlin: -------------------------------------------------------------------------------- 1 | ####{BSB GENERATED: NO EDIT 2 | FLG -ppx '/Users/ryan/Documents/dev/bs-loader/packages/reason-webpack-plugin/example/node_modules/bs-platform/lib/reactjs_jsx_ppx_2.exe' 3 | FLG -ppx /Users/ryan/Documents/dev/bs-loader/packages/reason-webpack-plugin/example/node_modules/bs-platform/lib/bsppx.exe 4 | S /Users/ryan/Documents/dev/bs-loader/packages/reason-webpack-plugin/example/node_modules/bs-platform/lib/ocaml 5 | B /Users/ryan/Documents/dev/bs-loader/packages/reason-webpack-plugin/example/node_modules/bs-platform/lib/ocaml 6 | FLG -nostdlib -no-alias-deps -color always 7 | FLG -w -30-40+6+7+27+32..39+44+45+101 8 | S src 9 | B lib/bs/src 10 | ####BSB GENERATED: NO EDIT} 11 | -------------------------------------------------------------------------------- /packages/reason-webpack-plugin/example/bsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reason-webpack-plugin-example", 3 | "sources": ["src"], 4 | "reason": { 5 | "react-jsx": 2 6 | }, 7 | "bsc-flags": ["-bs-super-errors"], 8 | "refmt": 3, 9 | "package-specs": { 10 | "module": "es6", 11 | "in-source": true 12 | }, 13 | "suffix": ".bs.js" 14 | } 15 | -------------------------------------------------------------------------------- /packages/reason-webpack-plugin/example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "version": "1.0.0", 4 | "private": true, 5 | "description": "", 6 | "main": "webpack.config.js", 7 | "scripts": { 8 | "build": "webpack" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "devDependencies": { 14 | "bs-platform": "^2.2.1", 15 | "webpack": "^3.5.5" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/reason-webpack-plugin/example/src/index.js: -------------------------------------------------------------------------------- 1 | import { addAndPrint } from './print.bs' 2 | 3 | addAndPrint(200, 400) 4 | -------------------------------------------------------------------------------- /packages/reason-webpack-plugin/example/src/print.re: -------------------------------------------------------------------------------- 1 | let addAndPrint = (x, z) => Js.log(x + z); 2 | -------------------------------------------------------------------------------- /packages/reason-webpack-plugin/example/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const ReasonPlugin = require('../') 3 | 4 | module.exports = { 5 | entry: './src/index.js', 6 | output: { 7 | filename: 'out.js', 8 | path: path.join(__dirname, 'build') 9 | }, 10 | plugins: [new ReasonPlugin()] 11 | } 12 | -------------------------------------------------------------------------------- /packages/reason-webpack-plugin/index.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | const bsb = require('bsb-js') 4 | /*:: import type { WebpackCompilerInstance } from 'webpack' */ 5 | 6 | class ReasonPlugin { 7 | apply(compiler /*: WebpackCompilerInstance */) { 8 | compiler.plugin('before-compile', async (compilationParams, cb) => { 9 | await bsb.runBuild(process.cwd()) 10 | cb() 11 | }) 12 | } 13 | } 14 | 15 | module.exports = ReasonPlugin 16 | -------------------------------------------------------------------------------- /packages/reason-webpack-plugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reason-webpack-plugin", 3 | "version": "2.0.1", 4 | "description": "Webpack plugin to run BSB on changes", 5 | "main": "index.js", 6 | "files": [ 7 | "index.js" 8 | ], 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/reasonml-community/bs-loader.git" 15 | }, 16 | "keywords": [ 17 | "webpack", 18 | "reason", 19 | "reasonml", 20 | "bucklescript" 21 | ], 22 | "author": "Ryan Delaney ", 23 | "license": "MIT", 24 | "bugs": { 25 | "url": "https://github.com/reasonml-community/bs-loader/issues" 26 | }, 27 | "homepage": "https://github.com/reasonml-community/bs-loader#readme", 28 | "dependencies": { 29 | "bsb-js": "^1.0.2" 30 | } 31 | } 32 | --------------------------------------------------------------------------------