├── .eslintrc ├── .github └── workflows │ └── semgrep.yml ├── .gitignore ├── .npmrc ├── README.md ├── bin └── wt-bundle ├── example ├── README.md ├── lib │ └── index.js ├── package.json ├── server.js └── webtask.js ├── index.js ├── jsconfig.json ├── lib ├── compiler.js └── config.js ├── opslevel.yml ├── package.json └── test ├── bundling.js └── fixtures ├── webtask-with-async-await ├── .eslintrc ├── index.js └── package.json ├── webtask-with-core-js ├── index.js └── package.json ├── webtask-with-deep-import ├── .eslintrc ├── index.js └── package.json ├── webtask-with-invalid-verquire ├── index.js └── package.json ├── webtask-with-simple-dep ├── index.js └── package.json └── webtask-with-valid-verquire ├── index.js └── package.json /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parserOptions": { 3 | "ecmaVersion": 6 4 | }, 5 | "env": { 6 | "es6": true, 7 | "node": true 8 | }, 9 | "extends": "eslint:recommended" 10 | } 11 | -------------------------------------------------------------------------------- /.github/workflows/semgrep.yml: -------------------------------------------------------------------------------- 1 | name: Semgrep 2 | 3 | on: 4 | pull_request_target: {} 5 | push: 6 | branches: ["master", "main"] 7 | permissions: 8 | contents: read 9 | jobs: 10 | semgrep: 11 | name: Scan 12 | runs-on: ubuntu-latest 13 | container: 14 | image: returntocorp/semgrep 15 | if: (github.actor != 'dependabot[bot]' && github.actor != 'snyk-bot') 16 | steps: 17 | - uses: actions/checkout@v3 18 | - run: semgrep ci 19 | env: 20 | SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }} 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | npm-debug.log 4 | .vscode 5 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DISCLAIMER 2 | 3 | **As of version 3, webtask bundle no longer does any module resolution as this is now handled by [`wt-cli`](https://github.com/auth0/wt-cli). Users who are building bundled webtasks should use `wt` with the `--bundle` option instead** 4 | 5 | # Webtask Bundle: because sometimes one file isn't enough 6 | 7 | Command line tool and node module for bundling your code to use on [webtask.io](https://webtask.io). 8 | 9 | **Features** 10 | 11 | * Organize your [webtask](https://webtask.io) code however you like 12 | * Work with any modules available on [npm](https://www.npmjs.com/) 13 | * Only bundle the modules that are not natively [available](https://tehsis.github.io/webtaskio-canirequire/) on the [webtask](https://webtask.io) platform 14 | 15 | ## Setup 16 | 17 | ```bash 18 | $ npm i -g webtask-bundle 19 | $ wt-bundle --watch --output ./build/webtask.js ./src/webtask.js 20 | ``` 21 | 22 | ## Contributing 23 | 24 | Just clone the repo, run `npm install` and then hack away. 25 | 26 | ## Issue reporting 27 | 28 | If you have found a bug or if you have a feature request, please report them at 29 | this repository issues section. Please do not report security vulnerabilities on 30 | the public GitHub issue tracker. The 31 | [Responsible Disclosure Program](https://auth0.com/whitehat) details the 32 | procedure for disclosing security issues. 33 | 34 | ## License 35 | 36 | MIT 37 | 38 | ## What is Auth0? 39 | 40 | Auth0 helps you to: 41 | 42 | * Add authentication with [multiple authentication sources](https://docs.auth0.com/identityproviders), either social like **Google, Facebook, Microsoft Account, LinkedIn, GitHub, Twitter, Box, Salesforce, amont others**, or enterprise identity systems like **Windows Azure AD, Google Apps, Active Directory, ADFS or any SAML Identity Provider**. 43 | * Add authentication through more traditional **[username/password databases](https://docs.auth0.com/mysql-connection-tutorial)**. 44 | * Add support for **[linking different user accounts](https://docs.auth0.com/link-accounts)** with the same user. 45 | * Support for generating signed [Json Web Tokens](https://docs.auth0.com/jwt) to call your APIs and **flow the user identity** securely. 46 | * Analytics of how, when and where users are logging in. 47 | * Pull data from other sources and add it to the user profile, through [JavaScript rules](https://docs.auth0.com/rules). 48 | 49 | ## Create a free account in Auth0 50 | 51 | 1. Go to [Auth0](https://auth0.com) and click Sign Up. 52 | 2. Use Google, GitHub or Microsoft Account to login. 53 | 54 | -------------------------------------------------------------------------------- /bin/wt-bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const ArgumentParser = require('argparse').ArgumentParser; 4 | const Bundler = require('../'); 5 | const Fs = require('fs'); 6 | const Mkdirp = require('mkdirp'); 7 | const Package = require('../package.json'); 8 | const Path = require('path'); 9 | 10 | 11 | const parser = new ArgumentParser({ 12 | description: 'Intelligently bundle your code for https://webtask.io', 13 | epilog: 'See https://webtask.io/docs for more information', 14 | prog: Object.keys(Package.bin)[0], 15 | version: Package.version, 16 | addHelp: true, 17 | }); 18 | 19 | const bundleArgs = parser.addArgumentGroup({ 20 | title: 'Bundling', 21 | // description: 'Options related to the default bundle mode.', 22 | }); 23 | 24 | bundleArgs.addArgument( 25 | ['--strict'], 26 | { 27 | help: 'Enable the strict Semver versioning test for required modules', 28 | action: 'storeTrue', 29 | defaultValue: false, 30 | dest: 'strict', 31 | } 32 | ); 33 | 34 | bundleArgs.addArgument( 35 | ['-m', '--minify'], 36 | { 37 | help: 'Generate a minified production build', 38 | action: 'storeTrue', 39 | defaultValue: false, 40 | dest: 'minify', 41 | } 42 | ); 43 | 44 | bundleArgs.addArgument( 45 | ['-o', '--output'], 46 | { 47 | help: 'Write the bundled code to a file instead of stdout', 48 | type: 'string', 49 | dest: 'output', 50 | metavar: '' 51 | } 52 | ); 53 | 54 | bundleArgs.addArgument( 55 | ['-n', '--node-version'], 56 | { 57 | help: 'Transpile code for the specified node version', 58 | type: 'string', 59 | dest: 'nodeVersion', 60 | defaultValue: process.version.replace(/^v/, ''), 61 | metavar: '' 62 | } 63 | ); 64 | 65 | bundleArgs.addArgument( 66 | ['-w', '--watch'], 67 | { 68 | help: 'Watch the source file for changes', 69 | action: 'storeTrue', 70 | defaultValue: false, 71 | dest: 'watch', 72 | } 73 | ); 74 | 75 | parser.addArgument( 76 | ['filename'], 77 | { 78 | metavar: '', 79 | type: String, 80 | help: 'Entrypoint filename for your webtask code', 81 | defaultValue: './webtask.js', 82 | } 83 | ); 84 | 85 | 86 | var args = parser.parseArgs(); 87 | 88 | if (args.watch && !args.output) { 89 | return exitError('An `ouput` path is required when `watch` is enabled', { showHelp: true }); 90 | } 91 | 92 | var bundle$ = Bundler.bundle({ 93 | entry: Path.resolve(Path.join(process.cwd(), args.filename)), 94 | loose: !args.strict, 95 | minify: args.minify, 96 | nodeVersion: args.nodeVersion, 97 | watch: args.watch, 98 | }); 99 | 100 | bundle$.subscribe(onNext, onError, onComplete); 101 | 102 | 103 | function onNext(build) { 104 | if (build.stats.errors.length) { 105 | // eslint-disable-next-line no-console 106 | console.error('Build failed at generation %d with errors:', build.generation); 107 | // eslint-disable-next-line no-console 108 | build.stats.errors.forEach(error => console.error(error.stack || error)); 109 | return; 110 | } 111 | 112 | if (args.output) { 113 | if (args.watch) { 114 | // eslint-disable-next-line no-console 115 | console.log('Successfully built code at generation %d', build.generation); 116 | } 117 | 118 | Mkdirp(Path.dirname(args.output), function (err) { 119 | if (err) { 120 | return exitError('Error creating the output directory: ' + err.message); 121 | } 122 | 123 | Fs.writeFile(args.output, build.code, 'utf8', function (err) { 124 | if (err) { 125 | return exitError('Error writing output to `' + Path.basename(args.output) + '`: ' + err.message); 126 | } 127 | 128 | // eslint-disable-next-line no-console 129 | console.log('Bundle successfully written to `%s`', args.output); 130 | }); 131 | }); 132 | } else { 133 | // eslint-disable-next-line no-console 134 | console.log(build.code); 135 | } 136 | } 137 | 138 | function onError(err) { 139 | // eslint-disable-next-line no-console 140 | console.error(err.stack); 141 | } 142 | 143 | function onComplete() { 144 | } 145 | 146 | function exitError(message, options) { 147 | if (!options) options = {}; 148 | 149 | var exitCode = typeof options.exitCode === 'undefined' 150 | ? 1 151 | : options.exitCode; 152 | 153 | // eslint-disable-next-line no-console 154 | console.error(message); 155 | 156 | if (options.showHelp) { 157 | parser.help(); 158 | } 159 | 160 | process.exit(exitCode); 161 | } 162 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # Example using `wt-bundle` 2 | 3 | This example represents a simple express server that is structured so that: 4 | 5 | 1. Your core server logic requires no changes to run on https://webtask.io or as a stand-alone server 6 | 2. When building for the webtask platform, any dependencies not available on the platform will be bundled for you 7 | 8 | ## Usage 9 | 10 | ### As a standalone server 11 | 12 | ```bash 13 | npm start 14 | ``` 15 | 16 | ### As a webtask 17 | 18 | **Note:** As a pre-requisite to running this example as a webtask, you must have [installed and configured wt-cli](https://github.com/auth0/wt-cli#setup). 19 | 20 | ```bash 21 | npm run bundle -- --prod --output ./build/webtask.js 22 | wt create --name wt-bundle ./build/webtask.js 23 | 24 | # Webtask url will be printed out. Your code is now running as a webtask at that url. 25 | ``` -------------------------------------------------------------------------------- /example/lib/index.js: -------------------------------------------------------------------------------- 1 | var Express = require('express'); 2 | // eslint-disable-next-line no-unused-vars 3 | var Joi = require('joi'); // I know that this is not on sandbox. Let webpack bundle it for webtask usage. 4 | // eslint-disable-next-line no-unused-vars 5 | var Package = require('../package.json'); // Test of loading json 6 | 7 | 8 | var app = Express(); 9 | var router = Express.Router(); 10 | 11 | // Set up any middleware 12 | app.use(router); 13 | 14 | 15 | router.all('*', handleRoot); 16 | 17 | 18 | module.exports = app; 19 | 20 | 21 | 22 | function handleRoot(req, res) { 23 | res.send('

Webtask? Heroku? Does it matter anymore?

'); 24 | } 25 | 26 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "version": "1.0.0", 4 | "main": "server.js", 5 | "scripts": { 6 | "bundle": "wt-bundle webtask.js --output ./build/webtask.js", 7 | "start": "node server.js" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "express": "^4.12.0", 14 | "joi": "^2.9.0", 15 | "webtask-tools": "^1.3.0" 16 | }, 17 | "devDependencies": {}, 18 | "description": "" 19 | } -------------------------------------------------------------------------------- /example/server.js: -------------------------------------------------------------------------------- 1 | var Express = require('express'); 2 | 3 | 4 | var app = require('./lib'); 5 | var server = Express(); 6 | var port = process.env.PORT || 3000; 7 | 8 | 9 | server.use(mockWebtaskContext); 10 | server.use(app); 11 | 12 | server.listen(port, function () { 13 | // eslint-disable-next-line no-console 14 | console.log('Server started on port', port); 15 | }); 16 | 17 | 18 | function mockWebtaskContext(req, res, next) { 19 | // Mock `req.webtaskContext` for standalone servers 20 | if (!req.webtaskContext) { 21 | req.webtaskContext = { 22 | secrets: {}, 23 | data: {}, 24 | }; 25 | } 26 | 27 | next(); 28 | } 29 | -------------------------------------------------------------------------------- /example/webtask.js: -------------------------------------------------------------------------------- 1 | var Webtask = require('webtask-tools'); 2 | 3 | // This is the entry-point for the Webpack build. We need to convert our module 4 | // (which is a simple Express server) into a Webtask-compatible function. 5 | module.exports = Webtask.fromExpress(require('./lib')); -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Compiler = require('./lib/compiler'); 4 | const Config = require('./lib/config'); 5 | const Rx = require('rxjs'); 6 | 7 | 8 | module.exports = { 9 | bundle, 10 | }; 11 | 12 | 13 | function bundle(options) { 14 | if (typeof options !== 'object') { 15 | return Rx.Observable.throw(new Error('Options must be an object')); 16 | } 17 | 18 | if (!options.entry) { 19 | return Rx.Observable.throw(new Error('The `entry` option is required')); 20 | } 21 | 22 | if (!options.name) { 23 | options.name = 'webtask'; 24 | } 25 | 26 | const webpackConfig = Config.create(options); 27 | 28 | return Rx.Observable.of(webpackConfig) 29 | .map(webpackConfig => ({ 30 | webpackConfig, 31 | watch: !!options.watch, 32 | })) 33 | .mergeMap(Compiler.compile); 34 | } 35 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES6" 4 | }, 5 | "exclude": [ 6 | "node_modules" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /lib/compiler.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const MemoryFs = require('memory-fs'); 4 | const Rx = require('rxjs'); 5 | const Webpack = require('webpack'); 6 | 7 | 8 | module.exports = { 9 | compile, 10 | }; 11 | 12 | 13 | function compile(options) { 14 | const memFs = new MemoryFs(); 15 | const compiler = Webpack(options.webpackConfig); 16 | let generation = 0; 17 | 18 | compiler.outputFileSystem = memFs; 19 | 20 | return Rx.Observable.create(function (subscriber) { 21 | if (options.watch) { 22 | const watcher = compiler.watch({}, onWatch); 23 | 24 | // Return an async disposer function 25 | return Rx.Observable.defer(function () { 26 | return Rx.Observable.bindNodeCallback(watcher.close.bind(watcher)); 27 | }); 28 | } else { 29 | compiler.run(onRun); 30 | } 31 | 32 | function onGeneration(stats) { 33 | try { 34 | const info = stats.toJson(); 35 | const code = stats.hasErrors() 36 | ? undefined 37 | : memFs.readFileSync('/bundle.js', 'utf8'); 38 | 39 | subscriber.next({ 40 | code: `const webtaskApi = module.webtask;\n${ code }`, 41 | generation: ++generation, 42 | stats: info, 43 | config: options.webpackConfig, 44 | }); 45 | } catch (e) { 46 | subscriber.error(e); 47 | } 48 | } 49 | 50 | function onRun(err, stats) { 51 | if (err) { 52 | return subscriber.error(err); 53 | } 54 | 55 | onGeneration(stats); 56 | 57 | subscriber.complete(); 58 | } 59 | 60 | function onWatch(err, stats) { 61 | if (err) { 62 | return subscriber.error(err); 63 | } 64 | 65 | onGeneration(stats); 66 | } 67 | }); 68 | } 69 | -------------------------------------------------------------------------------- /lib/config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Path = require('path'); 4 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); 5 | 6 | module.exports = { 7 | create, 8 | }; 9 | 10 | function create(options) { 11 | const dependencies = options.dependencies || {}; 12 | const isBareModuleRx = /^(?![./\\]|[a-zA-Z]:)/; 13 | const moduleSpecRx = /^((?:@[^/]+\/)?[^/]+)/; 14 | const useBabel = !options.disableTranspilation; 15 | 16 | const jsLoaders = [ 17 | { 18 | options: { 19 | 'module.webtask': '>webtaskApi', 20 | }, 21 | loader: require.resolve('imports-loader'), 22 | }, 23 | ]; 24 | 25 | if (useBabel) { 26 | jsLoaders.push({ 27 | options: { 28 | presets: [[require.resolve('@babel/preset-env'), { 29 | targets: { 30 | node: options.nodeVersion || '4', 31 | }, 32 | useBuiltIns: 'usage', 33 | }]], 34 | }, 35 | loader: require.resolve('babel-loader'), 36 | }); 37 | } 38 | 39 | const config = { 40 | entry: { 41 | [options.name]: options.entry, 42 | }, 43 | externals(context, request, cb) { 44 | if (!isBareModuleRx.test(request)) { 45 | // This is not a 'bare module' specifier. Include this. 46 | return cb(); 47 | } 48 | 49 | const matches = request.match(moduleSpecRx); 50 | 51 | if (!matches) { 52 | // This isn't something our regex understands. Let's bundle it to be safe. 53 | return cb(); 54 | } 55 | 56 | const moduleName = matches[1]; 57 | 58 | if (!dependencies[moduleName]) { 59 | // The module isn't specified in dependencies so we need to bundle it. 60 | return cb(); 61 | } 62 | 63 | return cb(null, `commonjs2 ${request}`); 64 | }, 65 | bail: false, // https://github.com/webpack/webpack/issues/3324 (while closed, issue remains when bail: true) 66 | output: { 67 | path: '/', 68 | filename: 'bundle.js', 69 | publicPath: '/build/', 70 | library: 'webtask', 71 | libraryTarget: 'commonjs2', 72 | }, 73 | module: { 74 | rules: [ 75 | { 76 | resource: { 77 | test: /\.jsx?$/, 78 | exclude: /node_modules/, 79 | }, 80 | use: jsLoaders, 81 | }, 82 | { 83 | issuer: { 84 | exclude: /node_modules/, 85 | }, 86 | resource: { 87 | not: [/\.jsx?$/], 88 | }, 89 | use: { 90 | loader: require.resolve('raw-loader'), 91 | }, 92 | }, 93 | ], 94 | }, 95 | plugins: options.minify ? [new UglifyJsPlugin({ 96 | extractComments: { 97 | condition: 'all', 98 | banner: false, 99 | }, 100 | })] : [], 101 | resolve: { 102 | modules: [Path.join(process.cwd(), 'node_modules')], 103 | mainFields: ['module', 'main'], 104 | }, 105 | resolveLoader: { 106 | modules: [Path.join(__dirname, 'node_modules')], 107 | // moduleExtensions: ['', '.webpack-loader.js', '.web-loader.js', '.loader.js', '.js'], 108 | mainFields: ['webpackLoader', 'loader', 'module', 'main'], 109 | }, 110 | mode: 'development', 111 | devtool: false, 112 | node: { 113 | console: false, 114 | global: false, 115 | process: false, 116 | Buffer: false, 117 | __filename: false, 118 | __dirname: false, 119 | setImmediate: false, 120 | }, 121 | performance: { 122 | hints: false, 123 | }, 124 | target: 'node', 125 | }; 126 | 127 | return config; 128 | } 129 | -------------------------------------------------------------------------------- /opslevel.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1 3 | repository: 4 | owner: dx_extensibility 5 | tags: 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webtask-bundle", 3 | "version": "3.4.0", 4 | "description": "Bundle your webtask scripts", 5 | "main": "index.js", 6 | "bin": { 7 | "wt-bundle": "./bin/wt-bundle" 8 | }, 9 | "scripts": { 10 | "test": "lab -vf" 11 | }, 12 | "keywords": [ 13 | "webtask", 14 | "webtask.io", 15 | "bundle", 16 | "webpack" 17 | ], 18 | "author": "Geoff Goodman", 19 | "license": "MIT", 20 | "dependencies": { 21 | "@babel/core": "^7.0.0-beta.44", 22 | "@babel/polyfill": "^7.0.0-beta.44", 23 | "@babel/preset-env": "^7.0.0-beta.44", 24 | "argparse": "^1.0.10", 25 | "async": "^2.6.0", 26 | "babel-loader": "^8.0.0-beta.2", 27 | "imports-loader": "^0.7.1", 28 | "lodash": "^4.17.5", 29 | "memory-fs": "^0.3.0", 30 | "mkdirp": "^0.5.1", 31 | "raw-loader": "^0.5.1", 32 | "rxjs": "^5.5.10", 33 | "uglifyjs-webpack-plugin": "^1.3.0", 34 | "webpack": "^4.5.0" 35 | }, 36 | "devDependencies": { 37 | "code": "^4.1.0", 38 | "eslint": "^4.19.1", 39 | "lab": "^14.3.4" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /test/bundling.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | 4 | const Bundler = require('../'); 5 | const Code = require('code'); 6 | const Lab = require('lab'); 7 | const Path = require('path'); 8 | 9 | const lab = exports.lab = Lab.script(); 10 | const expect = Code.expect; 11 | 12 | 13 | lab.experiment('Webtask bundling', { parallel: true }, () => { 14 | lab.test('will succeed for a simple webtask', { timeout: 10000 }, done => { 15 | const dirname = Path.resolve(__dirname, './fixtures/webtask-with-simple-dep/'); 16 | const pkgJson = require(Path.join(dirname, 'package.json')); 17 | const bundle$ = Bundler.bundle({ 18 | dependencies: pkgJson.dependencies, 19 | entry: Path.resolve(dirname, 'index.js'), 20 | name: pkgJson.name, 21 | }); 22 | let output; 23 | let error; 24 | 25 | return void bundle$ 26 | .subscribe(_output => output = _output, _error => error = _error, () => { 27 | expect(error).to.not.exist(); 28 | expect(output).to.be.an.object(); 29 | expect(output.code).to.be.a.string(); 30 | expect(output.generation).to.equal(1); 31 | expect(output.stats).to.be.an.object(); 32 | expect(output.stats.errors).to.be.an.array(); 33 | expect(output.stats.errors.length).to.equal(0); 34 | 35 | done(); 36 | }); 37 | }); 38 | 39 | lab.test('will succeed with core-js elements', { timeout: 10000 }, done => { 40 | const dirname = Path.resolve(__dirname, './fixtures/webtask-with-core-js/'); 41 | const pkgJson = require(Path.join(dirname, 'package.json')); 42 | const bundle$ = Bundler.bundle({ 43 | dependencies: pkgJson.dependencies, 44 | entry: Path.resolve(dirname, 'index.js'), 45 | name: pkgJson.name, 46 | }); 47 | let output; 48 | let error; 49 | 50 | return void bundle$ 51 | .subscribe(_output => output = _output, _error => error = _error, () => { 52 | expect(error).to.not.exist(); 53 | expect(output).to.be.an.object(); 54 | expect(output.code).to.be.a.string(); 55 | expect(output.generation).to.equal(1); 56 | expect(output.stats).to.be.an.object(); 57 | expect(output.stats.errors).to.be.an.array(); 58 | expect(output.stats.errors.length).to.equal(0); 59 | 60 | done(); 61 | }); 62 | }); 63 | 64 | lab.test('will succeed with async / await in node 4.8', { timeout: 10000 }, done => { 65 | const dirname = Path.resolve(__dirname, './fixtures/webtask-with-async-await/'); 66 | const pkgJson = require(Path.join(dirname, 'package.json')); 67 | const bundle$ = Bundler.bundle({ 68 | dependencies: pkgJson.dependencies, 69 | entry: Path.resolve(dirname, 'index.js'), 70 | name: pkgJson.name, 71 | nodeVersion: '4.8', 72 | }); 73 | let output; 74 | let error; 75 | 76 | return void bundle$ 77 | .subscribe(_output => output = _output, _error => error = _error, () => { 78 | expect(error).to.not.exist(); 79 | expect(output).to.be.an.object(); 80 | expect(output.code).to.be.a.string(); 81 | expect(output.generation).to.equal(1); 82 | expect(output.stats).to.be.an.object(); 83 | expect(output.stats.errors).to.be.an.array(); 84 | expect(output.stats.errors.length).to.equal(0); 85 | 86 | done(); 87 | }); 88 | }); 89 | 90 | lab.test('will succeed with async / await in node 8.9', { timeout: 10000 }, done => { 91 | const dirname = Path.resolve(__dirname, './fixtures/webtask-with-async-await/'); 92 | const pkgJson = require(Path.join(dirname, 'package.json')); 93 | const bundle$ = Bundler.bundle({ 94 | dependencies: pkgJson.dependencies, 95 | entry: Path.resolve(dirname, 'index.js'), 96 | name: pkgJson.name, 97 | nodeVersion: '8.9', 98 | }); 99 | let output; 100 | let error; 101 | 102 | return void bundle$ 103 | .subscribe(_output => output = _output, _error => error = _error, () => { 104 | expect(error).to.not.exist(); 105 | expect(output).to.be.an.object(); 106 | expect(output.code).to.be.a.string(); 107 | expect(output.generation).to.equal(1); 108 | expect(output.stats).to.be.an.object(); 109 | expect(output.stats.errors).to.be.an.array(); 110 | expect(output.stats.errors.length).to.equal(0); 111 | 112 | done(); 113 | }); 114 | }); 115 | 116 | lab.test('will correctly bundle deep imports', { timeout: 10000 }, done => { 117 | const dirname = Path.resolve(__dirname, './fixtures/webtask-with-deep-import/'); 118 | const pkgJson = require(Path.join(dirname, 'package.json')); 119 | const bundle$ = Bundler.bundle({ 120 | dependencies: pkgJson.dependencies, 121 | entry: Path.resolve(dirname, 'index.js'), 122 | name: pkgJson.name, 123 | nodeVersion: '8.9', 124 | }); 125 | let output; 126 | let error; 127 | 128 | return void bundle$ 129 | .subscribe(_output => output = _output, _error => error = _error, () => { 130 | expect(error).to.not.exist(); 131 | expect(output).to.be.an.object(); 132 | expect(output.code).to.be.a.string(); 133 | expect(output.generation).to.equal(1); 134 | expect(output.stats).to.be.an.object(); 135 | expect(output.stats.errors).to.be.an.array(); 136 | expect(output.stats.errors.length).to.equal(0); 137 | expect(output.stats.modules.length).to.equal(2); 138 | 139 | done(); 140 | }); 141 | }); 142 | }); 143 | 144 | if (require.main === module) { 145 | Lab.report([lab], { output: process.stdout, progress: 2 }); 146 | } 147 | -------------------------------------------------------------------------------- /test/fixtures/webtask-with-async-await/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parserOptions": { 3 | "ecmaVersion": 2017 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/webtask-with-async-await/index.js: -------------------------------------------------------------------------------- 1 | module.exports = async (ctx, cb) => { 2 | await new Promise(resolve => setTimeout(resolve, 2000)); 3 | 4 | cb(null, { 5 | 'Object.keys': Object.keys(ctx), 6 | 'JSON.stringify': JSON.stringify(ctx.secrets), 7 | }); 8 | } 9 | -------------------------------------------------------------------------------- /test/fixtures/webtask-with-async-await/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webtask-with-core-js", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /test/fixtures/webtask-with-core-js/index.js: -------------------------------------------------------------------------------- 1 | module.exports = (ctx, cb) => { 2 | cb(null, { 3 | 'Object.keys': Object.keys(ctx), 4 | 'JSON.stringify': JSON.stringify(ctx.secrets), 5 | }); 6 | } -------------------------------------------------------------------------------- /test/fixtures/webtask-with-core-js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webtask-with-core-js", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /test/fixtures/webtask-with-deep-import/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parserOptions": { 3 | "ecmaVersion": 2017, 4 | "sourceType": "module" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/webtask-with-deep-import/index.js: -------------------------------------------------------------------------------- 1 | import map from 'lodash/map'; 2 | 3 | export default (cb) => { 4 | cb(null, map.toString()); 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/webtask-with-deep-import/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webtask-with-deep-import", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "lodash": "^4.17.10" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/fixtures/webtask-with-invalid-verquire/index.js: -------------------------------------------------------------------------------- 1 | module.exports = (cb) => { 2 | cb(null, Object.keys(require('request@20000.0.0'))); 3 | }; -------------------------------------------------------------------------------- /test/fixtures/webtask-with-invalid-verquire/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webtask-with-invalid-verquire", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /test/fixtures/webtask-with-simple-dep/index.js: -------------------------------------------------------------------------------- 1 | module.exports = (cb) => { 2 | cb(null, require('webtask-test-module-1')); 3 | } -------------------------------------------------------------------------------- /test/fixtures/webtask-with-simple-dep/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webtask-with-simple-dep", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "webtask-test-module-1": "^1.0.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/fixtures/webtask-with-valid-verquire/index.js: -------------------------------------------------------------------------------- 1 | module.exports = (cb) => { 2 | cb(null, Object.keys(require('request@2.27.0'))); 3 | }; -------------------------------------------------------------------------------- /test/fixtures/webtask-with-valid-verquire/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webtask-with-valid-verquire", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | --------------------------------------------------------------------------------