Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Storage] Rollup for tests in storage #2297

Merged
merged 45 commits into from May 15, 2019

Conversation

HarshaNalluru
Copy link
Member

@HarshaNalluru HarshaNalluru commented Apr 16, 2019

  • Update rollup-config as per the template.
  • Rollup for both the node and browser tests
  • Updated test:node command to use the generated dist-test/index.node.js instead of running ts-node on the test files.

"test:node": "cross-env TS_NODE_COMPILER_OPTIONS="{\"module\": \"commonjs\"}" nyc mocha --compilers ts-node/register --require source-map-support/register --reporter mocha-multi-reporters --reporter-options configFile=mocha.reporter.config.json --full-trace --no-timeouts test/*.test.ts test/node/*.test.ts",

updated to

"test:node": "mocha --reporter mocha-multi-reporters --reporter-options configFile=mocha.reporter.config.json -t 120000 dist-test/index.node.js",

  • Minor changes to rollup.base.config.js to get rollup working.
  • Restructured commands in package.json.
  • Renamed test files for consistency across packages.
  • Updated .nycrc to get code coverage with the updated version of nyc(14.0.0).

@HarshaNalluru HarshaNalluru self-assigned this Apr 16, 2019
@HarshaNalluru HarshaNalluru added Storage Storage Service (Queues, Blobs, Files) EngSys This issue is impacting the engineering system. labels Apr 16, 2019
"browser/azure-storage.blob.min.js",
"browser/*.txt"
])
.src(["browser/index.js", "browser/*.txt"])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we still want the minified version. The template uses the uglify rollup plugin to do that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[ Offline discussion with Jeremy ]

  • As per the template, the generated file is - browser/index.js (minified version)
  • This PR uses rollup-plugin-uglify to generate the minified version ("browser/index.js") just like the template does
  • Not sure if we should generate both the files
    ["browser/azure-storage.blob.js", "browser/azure-storage.blob.min.js" ]
    the way storage-blob previously does
  • Still have to decide on the names for generated outputs!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My thoughts here: the standalone unminified version seems not important for npm package scenarios, but is possibly important when downloading a .zip release from e.g. GitHub. If we go the GH release route, we should have an unminified version, but otherwise I'm fine leaving it out. I'll also note that the unminified code will likely not be super nice to debug as it will still be bundled and have a bunch of "plumbing" goop.

In terms of file names we discussed on teams, how about we go with the following rule: the bundle file name is the package name with @ removed, / replaced with -, and suffixed with .min if minified. So azure-storage-blob.min.js.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Modify template to generate both minified and unminified versions of src code through rollup and update the names of outputs"
Issue to track - #2416

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both js and min.js are needed in the generated zip bundle to be published. See https://aka.ms/downloadazurestoragejsblob

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes @XiaoningLiu, we are doing it now.
Now, the generated zip bundle contains both "azure-storage-blob.min.js" and "azure-storage-blob.js"

Copy link
Contributor

@jeremymeng jeremymeng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please work on adding uglify.

Also I am not sure whether we should keep the old file names for browser. @bterlson what's recommended for naming js files for browser?

"browser/azure-storage.blob.min.js",
"browser/*.txt"
])
.src(["browser/index.js", "browser/*.txt"])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My thoughts here: the standalone unminified version seems not important for npm package scenarios, but is possibly important when downloading a .zip release from e.g. GitHub. If we go the GH release route, we should have an unminified version, but otherwise I'm fine leaving it out. I'll also note that the unminified code will likely not be super nice to debug as it will still be bundled and have a bunch of "plumbing" goop.

In terms of file names we discussed on teams, how about we go with the following rule: the bundle file name is the package name with @ removed, / replaced with -, and suffixed with .min if minified. So azure-storage-blob.min.js.

return;
}

if (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need this custom onwarn machinery? It's included in the template as an example, but if it's not needed here feel free to remove it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I remember facing an issue with "this" which got resolved when I added this(for browser)
I'll verify once again.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

**Removed chai warning block(not required).
"THIS_IS_UNDEFINED" is required

file: "browser/index.js",
banner: banner,
format: "umd",
name: "azblob",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a note: this will likely change to align with .net naming conventions. Expect something like Azure.Storage.Blob instead, but let's keep it the same for now.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't change this before next breaking change. : )

}
),
// os is not used by the browser bundle, so just shim it
shim({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these shims actually needed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • dotenv is needed
  • os is present from the beginning

Update - shimming both of them is required.

plugins: [
sourcemaps(),
replace(
// ms-rest-js is externalized so users must include it prior to using this bundle.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this comment is relevant and can be deleted IMO.

@@ -7,8 +7,8 @@ const zipFileName = `azurestoragejs.blob-${version}.zip`;
gulp.task("zip", function(callback) {
gulp
.src([
"browser/azure-storage.blob.js",
"browser/azure-storage.blob.min.js",
"browser/azure-storage-blob.min.js",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update section "JavaScript Bundle" in "readme.md". Same with other readme.md files for queue/file. Please check any documents points to old bundle name.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing out.
Done - 7788fd0

@@ -82,7 +83,7 @@
"prebuild": "npm run clean",
"pretest": "npm run build:test",
"test:browser": "karma start --single-run",
"test:node": "cross-env TS_NODE_COMPILER_OPTIONS=\"{\\\"module\\\": \\\"commonjs\\\"}\" nyc mocha --compilers ts-node/register --require source-map-support/register --reporter mocha-multi-reporters --reporter-options configFile=mocha.reporter.config.json --full-trace --no-timeouts test/*.test.ts test/node/*.test.ts",
"test:node": "nyc mocha --reporter mocha-multi-reporters --reporter-options configFile=mocha.reporter.config.json -t 120000 dist-test/index.node.js",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does coverage report look like? Do covered lines point to TS source code or compiled JS codes?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in the other thread.
#2297 (comment)

sourcemap: true
},
plugins: [
sourcemaps(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does "sourcemaps()" do? I remembered a sourcemap file is generated under dist folder without this plugin.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This plugin helps in grabbing source maps from sourceMappingURLs.

For instance, look at the differences in nyc code coverage output.

  • with sourcemaps()
    image

  • without sourcemaps()
    image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. Can you remove "dotenv" from coverage report?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sourcemaps is for threading the sourcemap across multiple transformations. Rollup by default won't consume sourcemaps so the dist sourcemaps would be a mapping to dist-esm rather than the original TS code.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. Can you remove "dotenv" from coverage report?

Update -

I tried excluding that specific file(and every possible node_modules path) by adding rules in .nycrc file and could not exclude this file in any way.

Looks like nyc is not properly honouring the exclude rule in .nycrc. I see some similar recent user issues in the nyc repo - istanbuljs/nyc#1099

I'm opening a new issue to investigate further - #2820

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@HarshaNalluru - I apologize. The issue 1099 that you reference was mine. It was user error.

}
}),
nodeResolve({ preferBuiltins: true }),
cjs(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is"common-js" plugin necessary? Previously we didn't have this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • cjs() converts CommonJS modules to ES6, so they can be included in a Rollup bundle.
  • This is required for proper functioning of the dotenv module.
  • dotenv module has been added to the storage packages as a devDependency - [Storage] Environment variables for storage sdk #1610. This package helps to load the environment variables from a .env file instead of setting them each time we run the tests.
  • Example use case
    import { getBSU, getUniqueName } from "./utils";
    import * as dotenv from "dotenv";
    dotenv.config({path:"../.env"});
    // tslint:disable:no-empty

}),
nodeResolve({ preferBuiltins: true }),
cjs(),
json()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is "json" plugin necessary?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my understanding, rollup-plugin-json is not necessary.
Removed it - 518a1f0

console.error(`(!) ${warning.message}`);
};
} else if (production) {
baseConfig.plugins.push(uglify());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For Node.js, we released minified CJS bundle to customers. When there is an exception in SDK, stack trace is unreadable. Any good suggestions? @bterlson @jeremymeng @HarshaNalluru

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sourcemaps! See below.

@@ -82,7 +83,7 @@
"prebuild": "npm run clean",
"pretest": "npm run build:test",
"test:browser": "karma start --single-run",
"test:node": "cross-env TS_NODE_COMPILER_OPTIONS=\"{\\\"module\\\": \\\"commonjs\\\"}\" nyc mocha --compilers ts-node/register --require source-map-support/register --reporter mocha-multi-reporters --reporter-options configFile=mocha.reporter.config.json --full-trace --no-timeouts test/*.test.ts test/node/*.test.ts",
"test:node": "nyc mocha --reporter mocha-multi-reporters --reporter-options configFile=mocha.reporter.config.json -t 120000 dist-test/index.node.js",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When we test against a single bundle file, failed case reported stack trace is not friendly (not pointing to original TS files), makes it difficulty to locate to specific line for debugging. Especially to debug failed cases reported in CIs. Any good suggestions?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good question. But currently, we don't have a way.
(Even for other packages, reported stack trace doesn't point to the original TS files).
I can start a new issue to track this.

[On a side note, a single bundle file would help us enable VS Code debugging effortlessly.]

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aha, how did you debug in VS code with a single bundle file? will break point work properly? I previously use node-ts, and it works great especial for break points debugging.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will point to the source files(typescript) using the source mappings.
We can set breakpoints in the typescript source files.

Created a draft PR for VS Code Debugging -
https://github.com/Azure/azure-sdk-for-js/pull/2770/files#diff-8b42a0e706358bbff6b0a06ac092e5ac.

Once this setup is done, we would basically never have to update anything in the VS Code launch.json since the configuration will correspond to all the tests.

[Contains changes from this PR, can only be merged after this PR for rollup]

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, that's very useful!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Source maps with vscode are pretty sweet. But there is also this library we could investigate as a dev dependency: https://github.com/evanw/node-source-map-support. It maps all the file/offset data in exception payloads using sourcemaps.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Brian, creating a new issue to track this - #2792

// mark assert as external
baseConfig.external.push("assert", "fs", "path");

baseConfig.onwarn = warning => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, for 10.1.0-preview, we have similar roll up config for Node.js test cases. However, doesn't have met this "THIS_IS_UNDEFINED" warning. Can you check why previous version doesn't have this issue?

See https://github.com/Azure/azure-storage-js/blob/v10.1.0-preview-blob/blob/rollup.test.config.js

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's possible this ignore was added because it was needed in other projects and isn't needed here. Harsha can confirm.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do see "THIS_IS_UNDEFINED" warning which I could only get rid of using custom onwarn handlers.
Also, I've verified v10.1.0-preview branch, I need to look deeper on why it didn't throw those warnings previously.
I'm guessing this might be from version updates in the dependencies[not really sure].

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update -

From the documentation https://rollupjs.org/guide/en#danger-zone, it is not clear to me on what context = "null" does.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @HarshaNalluru ! Here is the description about "THIS NOT DEFINED" in rollup doc. options.context is a workaround to override default value of this. @bterlson previously added node.context = "null" in v10.1.0-preview. I believe this approach should work.

Error: "this is undefined"
In a JavaScript module, this is undefined at the top level (i.e., outside functions). Because of that, Rollup will rewrite any this references to undefined so that the resulting behaviour matches what will happen when modules are natively supported.

There are occasional valid reasons for this to mean something else. If you're getting errors in your bundle, you can use options.context and options.moduleContext to change this behaviour.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed onwarn handlers and updated with context = "null"
2d2c526

Copy link
Member

@XiaoningLiu XiaoningLiu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally looks good to me, thanks @HarshaNalluru ! 2 comments left

  • dotenv is included in the coverage repo, should be remove
  • supress-warning for undefined this, we'd better find out the root cause, if there any better workaround to fix the issue instead of ignore the warning

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
EngSys This issue is impacting the engineering system. Storage Storage Service (Queues, Blobs, Files)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants