diff --git a/.gitignore b/.gitignore index b73123f4f8..232fe989a2 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,3 @@ target/ # Mac Temporary Files .DS_Store **/.DS_Store - -# Node Modules -**/node_modules/ diff --git a/dfx.nix b/dfx.nix index 17b86e163f..9f39b14637 100644 --- a/dfx.nix +++ b/dfx.nix @@ -69,7 +69,7 @@ let cp ${pkgs.motoko.didc}/bin/didc $out cp ${pkgs.motoko.rts}/rts/mo-rts.wasm $out mkdir $out/stdlib && cp -R ${pkgs.motoko.stdlib}/. $out/stdlib - mkdir $out/js-user-library && tar --strip-components=1 --directory=$out/js-user-library -xzvf ${userlib-js}/internet-computer-*.tgz + mkdir $out/js-user-library && cp -R ${userlib-js}/. $out/js-user-library ''; } ) diff --git a/src/dfx/assets/new_project_node_files/webpack.config.js b/src/dfx/assets/new_project_node_files/webpack.config.js index aef6b64bd3..b8185baa16 100644 --- a/src/dfx/assets/new_project_node_files/webpack.config.js +++ b/src/dfx/assets/new_project_node_files/webpack.config.js @@ -19,7 +19,7 @@ const aliases = Object.entries(dfxJson.canisters).reduce((acc, [name,value]) => process.env["HOME"], ".cache/dfinity/versions", dfxJson.dfx || process.env["DFX_VERSION"], - "js-user-library/", + "js-user-library/dist/lib.prod.js", ), }); diff --git a/src/dfx/src/commands/start.rs b/src/dfx/src/commands/start.rs index eb11a77308..d670398f28 100644 --- a/src/dfx/src/commands/start.rs +++ b/src/dfx/src/commands/start.rs @@ -100,7 +100,7 @@ pub fn exec(env: &dyn Environment, args: &ArgMatches<'_>) -> DfxResult { let bootstrap_dir = env .get_cache() - .get_binary_command_path("js-user-library/bootstrap")?; + .get_binary_command_path("js-user-library/dist/bootstrap")?; let frontend_watchdog = webserver( address_and_port, vec![url::Url::parse(IC_CLIENT_BIND_ADDR).unwrap()], diff --git a/src/userlib/js/.gitignore b/src/userlib/js/.gitignore index b605953ac2..eaa5c506e8 100644 --- a/src/userlib/js/.gitignore +++ b/src/userlib/js/.gitignore @@ -1,6 +1,3 @@ -build_info.json +dist/ +out/ node_modules/ -src/**/*.js -src/**/*.js.map -src/**/*.d.ts - diff --git a/src/userlib/js/.npmignore b/src/userlib/js/.npmignore deleted file mode 100644 index 93c3273f5f..0000000000 --- a/src/userlib/js/.npmignore +++ /dev/null @@ -1,13 +0,0 @@ -# We work with a safelist here, so block everything that's not permitted, and add packages -# that are. -** - -!bootstrap/** -!src/**/*.d.ts -!src/**/*.js -!types/**/*.d.ts -!package.json -!README.md - -# The following line further removes all test files (which matches .js and .d.ts). -src/**/*.test.* diff --git a/src/userlib/js/README.adoc b/src/userlib/js/README.adoc index be1c28d822..267e97f3d8 100644 --- a/src/userlib/js/README.adoc +++ b/src/userlib/js/README.adoc @@ -1,28 +1,5 @@ -= JavaScript User Library - -This is an internal document and is not published to NPM. The public facing README is in -`./README.md`. This file can be safely removed once we are open sourced. - -Package: `@internet-computer/userlib` += js-user-library == Development -=== How to build and use locally - -In this repo: - -[source,bash] -cd src/userlib/js # You are here -npm install -npm run build -pwd # Keep this -cp -rf . $(dfx cache show) - -Alternatively, it might be easier to simply create a symlink; - -[source,bash] -rm -rf $(dfx cache show)/js-user-library -ln -s src/userlib/js $(dfx cache show)/js-user-library - -Then you just need to run `npm run build` when you change the code. You can also use -`npm run build -- --watch` for a quick watch mode. +Run `nix-shell` in this directory, and then use `npm` as normal. diff --git a/src/userlib/js/README.md b/src/userlib/js/README.md deleted file mode 100644 index 7daea1e5c0..0000000000 --- a/src/userlib/js/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# JavaScript User Library - -Package: `@internet-computer/userlib` - -## API - -TBD. diff --git a/src/userlib/js/default.nix b/src/userlib/js/default.nix index 39775edd4c..7129e4d4d8 100644 --- a/src/userlib/js/default.nix +++ b/src/userlib/js/default.nix @@ -1,6 +1,5 @@ -{ pkgs ? import ../../../nix { inherit system; } -, system ? builtins.currentSystem -}: +{ pkgs }: + let repoRoot = ../../..; src = pkgs.lib.noNixFiles (pkgs.lib.gitOnlySource repoRoot ./.); @@ -8,7 +7,6 @@ in pkgs.napalm.buildPackage src { root = ./.; name = "dfinity-sdk-userlib-js"; - # ci script now does everything CI should do. Bundle is needed because it's the output # of the nix derivation. npmCommands = [ @@ -18,9 +16,9 @@ pkgs.napalm.buildPackage src { ]; installPhase = '' - npm pack mkdir -p $out - - cp internet-computer-*.tgz $out + cp -R dist $out + cp package.json $out + cp README.adoc $out ''; } diff --git a/src/userlib/js/package.json b/src/userlib/js/package.json index 68f7be7efb..515d0f5943 100644 --- a/src/userlib/js/package.json +++ b/src/userlib/js/package.json @@ -1,11 +1,17 @@ { "private": true, - "name": "@internet-computer/userlib", - "version": "0.5.0", - "main": "src/index.js", + "name": "@internet-computer/js-user-library", + "version": "0.1.0", + "main": "dist/lib.node.js", + "browser": { + "./dist/lib.node.js": "./dist/lib.web.js" + }, + "files": [ + "dist/**/*" + ], "scripts": { "build": "tsc -p tsconfig.json", - "bundle": "npm run build", + "bundle": "npm run build && webpack", "ci": "npm run prettier && npm run lint && npm run build && npm run test", "lint": "tslint --project tsconfig.json --config tslint.json", "lint:fix": "npm run lint -- --fix", diff --git a/src/userlib/js/tsconfig.json b/src/userlib/js/tsconfig.json index 511725e12c..707f221162 100644 --- a/src/userlib/js/tsconfig.json +++ b/src/userlib/js/tsconfig.json @@ -15,10 +15,10 @@ // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ "sourceMap": true, /* Generates corresponding '.map' file. */ // "outFile": "./", /* Concatenate and emit output to single file. */ - // "outDir": "out", /* Redirect output structure to the directory. */ + "outDir": "out", /* Redirect output structure to the directory. */ // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ // "composite": true, /* Enable project compilation */ - "tsBuildInfoFile": "./build_info.json", /* Specify file to store incremental compilation information */ + "tsBuildInfoFile": "./out/build_info.json", /* Specify file to store incremental compilation information */ // "removeComments": true, /* Do not emit comments to output. */ // "noEmit": true, /* Do not emit outputs. */ // "importHelpers": true, /* Import emit helpers from 'tslib'. */ diff --git a/src/userlib/js/webpack.config.js b/src/userlib/js/webpack.config.js new file mode 100644 index 0000000000..0dfbf7d6e9 --- /dev/null +++ b/src/userlib/js/webpack.config.js @@ -0,0 +1,116 @@ +const path = require("path"); +const webpack = require("webpack"); +const TerserPlugin = require('terser-webpack-plugin'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); + +const config = { + mode: "development", + entry: [ + "./out/index.js", + ], + devtool: "inline-source-map", + output: { + libraryTarget: "umd", + }, +}; + +const nodeConfig = { + ...config, + target: "node", + output: { + ...config.output, + filename: "lib.node.js", + }, + plugins: [ + new webpack.ProvidePlugin({ + crypto: "@trust/webcrypto", + fetch: "node-fetch", + TextEncoder: ["text-encoding", "TextEncoder"], + }), + ], +}; + +const webConfig = { + ...config, + target: "web", + output: { + ...config.output, + filename: "lib.web.js", + }, +}; + +const prodConfig = { + ...webConfig, + target: "web", + output: { + ...webConfig.output, + filename: "lib.prod.js", + }, + devtool: "source-map", + optimization: { + minimize: true, + minimizer: [ + new TerserPlugin({ + cache: true, + parallel: true, + sourceMap: true, // Must be set to true if using source-maps in production + terserOptions: { + ecma: 8, + minimize: true, + comments: false + // https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions + } + }), + ], + } +}; + +const bootstrapConfig = { + ...webConfig, + entry: "./bootstrap/index.js", + target: "web", + output: { + ...webConfig.output, + path: path.resolve(__dirname, "./dist/bootstrap"), + filename: "index.js", + }, + devtool: "none", + optimization: { + minimize: true, + minimizer: [ + new TerserPlugin({ + cache: true, + parallel: true, + sourceMap: true, // Must be set to true if using source-maps in production + terserOptions: { + ecma: 8, + minimize: true, + comments: false + // https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions + } + }), + ], + }, + plugins: [ + new HtmlWebpackPlugin({ + template: 'bootstrap/index.html', + filename: 'index.html' + }), + new HtmlWebpackPlugin({ + template: 'bootstrap/candid/index.html', + filename: 'candid/index.html' + }), + new CopyWebpackPlugin([{ + from: 'bootstrap/dfinity.png', + to: 'favicon.ico', + }]), + ] +}; + +module.exports = [ + nodeConfig, + webConfig, + prodConfig, + bootstrapConfig, +];