Monthly Archives: October 2018

Your Source Maps are Broken. Here's How to Fix Them

By Sentry

Source maps are awesome. Why? Because they are used to display your original JavaScript while debugging, which is a lot easier to look at than minified production code. In a sense, source maps are the decoder ring to your secret (minified) code.

However, they can be tricky to get working properly. If you’ve run into some trouble, the tips below will hopefully help you get everything in working order.

If you’re looking to get started with source maps for the first time, check out our earlier post, Debugging Minified JavaScript with Source Maps, before continuing.

Missing or incorrect source map directive

We’re going to presume that you’ve already produced a source map using a tool like UglifyJS or Webpack. But generating a source map isn’t worth diddly if the browser can’t find it. To do that, browser agents expect your bundled JavaScript files to contain either a sourceMappingURL comment or return a SourceMap HTTP header that points to the location of the source map.

To verify your source map directive is present and working, you need to:

Locate the sourceMappingURL comment at the very end of the file on its own line:

//# sourceMappingURL=script.min.js.map

This value must be a valid URI. If it is a relative URL, it is relative to the path location of the bundled JavaScript file (e.g., script.min.js). Most source map generation tools generate this value automatically for you, but also provide an option for overriding it.

Using UglifyJS, you can generate this comment by defining url=script.min.js.map in your source map options:

# Using UglifyJS 3.3
$ uglifyjs --source-map url=script.min.js.map,includeSources 
  --output script.min.js script.js

Using Webpack, specifying devtool: "source-map" in your Webpack config will enable source maps, and Webpack will output a sourceMappingURL directive in your final, minified file. You can customize the source map filename itself by specifying sourceMapFilename.

// webpack.config.js
module.exports = {
    // ...
    entry: {
      "app": "src/app.js"
    },
    output: {
      path: path.join(__dirname, 'dist'),
      filename: "[name].js",
      sourceMapFilename: "[name].js.map"
    },
    devtool: "source-map"
    // ...
};

Note that even if you generate sourceMappingURL properly, it’s possible that it isn’t appearing once you serve your final version in production. For example, another tool at the end of front-end build toolchain might be stripping comments — which would have the effect of removing //# sourceMappingURL.

Or your CDN might be doing something clever like stripping comments unknowingly; Cloudflare’s Autominify feature has stripped these comments in the past. Double-check your file in production to make sure your comment is there!

Alternatively: Ensure your server returns a valid SourceMap HTTP header

Instead of this magic sourceMappingURL comment, you can alternatively indicate the location of the source map by returning a SourceMap HTTP header value when requesting your minified file.

 SourceMap: /path/to/script.min.js.map

Just like sourceMappingURL, if this value is a relative path, it is relative to the path location of the bundled JavaScript file. Browser agents interpret the SourceMap HTTP header and sourceMappingURL identically.

Note that to serve this header, you need to configure your web server or CDN to do so. Many JavaScript developers may not have the capability of setting arbitrary headers on their static assets in production, so for most, it’s easier to just generate and use sourceMappingURL.

Missing original source files

Let’s assume that you’ve properly generated your source map, and your sourceMappingURL (or SourceMap header) is present and correct. Parts of the transformation are clearly working; for example, error stack traces now mention your original filenames and contain sensible line and column locations. But despite this improvement, there’s a big piece missing — you still can’t browse your original source files using your browser’s debug tools.

This likely means that your source map doesn’t contain or link to your original source files. Without your original source files, you’re still stuck stepping through minified code in your debugger. Ouch.

There are a handful of solutions for making your original source files available:

Inline your original source code into your source map via **sourcesContent**

It’s possible to inline your entire original source code into the source map itself. Inside the source map, this is referred to as sourcesContent. This can make for really large source map files (on the order of megabytes) but has the advantage of being really simple for browser agents to locate and link up all your original source files. If you’re struggling to get your browser to find your original sources, we recommend trying this.

If you’re using UglifyJS, you can inline your original source code into your source map’s sourcesContent property using the includeSources CLI option:

  uglifyjs --source-map url=script.min.js.map,includeSources --output script.min.js script.js

If you’re using Webpack, there’s nothing to do here — Webpack inlines your original source code into your source maps by default (assuming devtool:"source-map" is enabled).

Host your original source files and serve them publicly

Instead of inlining your original source files, you can instead host them on your web server such that they can be individually downloaded by browser agents. If you’re concerned about security — these are your original source files, after all — you can serve the files via localhost or make sure they’re protected behind a VPN (e.g., the files are only reachable via your company’s internal network).

Sentry users only: upload your source files as artifacts

If you’re a Sentry user and your primary goal is making sure source maps are available so that Sentry can unminify your stack traces and provide surrounding source code, you have a third option: upload your source files as artifacts using sentry-cli or directly via our API.

Of course, if you do either of the first two options — either inlining your original files or hosting them publicly — Sentry will find the content that way too. It’s your call.

Bad source maps caused by multiple transformations

If you’re using two or more JavaScript compilers invoked separately (e.g., Babel + UglifyJS), it’s possible to produce a source map that points to an intermediate transformed state of your code, rather than the original source code. This means that when you debug in the browser, the code you’re stepping through isn’t minified — an improvement for sure — but it’s still not a 1:1 match with your original source code.

For example, let’s say you used Babel to convert your ES2018 code to ES2015, then ran the output through UglifyJS:

# Using Babel 7.1 and UglifyJS 3.3
$ babel-cli script.js --presets=@babel/env | uglifyjs -o script.min.js 
  --source-map "filename=app.min.js.map"
$ ls script*
script.js script.min.js script.min.js.map

If you were to use the source map generated by this command, you’ll notice it won’t be accurate. That’s because the source map only converts from the minified (Uglified) code back to the code generated by Babel. It does not point back to your original source code.

Note this is also common if you’re using a task manager like Gulp or Grunt.

To fix this, there are two possible solutions:

Use a bundler like Webpack to manage all your transformations

Instead of using Babel or UglifyJS separately, use them instead as Webpack plugins (e.g., babel-loader and uglifyjs-webpack-plugin). Webpack will produce a single source map that transforms from the final result back to your original source code, even though there are multiple transformations taking place under the hood.

Use a library to “stitch” together source maps between transformations

If you’re committed to using multiple compilers separately, you can use a library like source-map-merger, or the source-map-loader Webpack plugin, to feed the results of an earlier source map into a subsequent transformation.

If you have a choice in the matter, we’d recommend pursuing the first option — just use Webpack and save yourself some grief.

Files are incorrectly versioned or missing versions

Let’s say you’ve followed all of the above. Your sourceMappingURL (or SourceMap HTTP header) is present and properly declared. Your source maps include your original source files (or they’re publicly accessible). And you’re using Webpack end-to-end to manage your transformations. And yet, your source maps still periodically create mappings that don’t match.

There’s a remaining possibility: bad transforms caused by mismatched compiled files and source maps.

This happens when a browser or tool downloads a compiled file (e.g., script.min.js), then attempts to fetch its corresponding source map (script.min.js.map), but the source map it downloads is “newer” and corresponds to a different version of that compiled file.

This situation is uncommon but can occur if a deploy is triggered while you’re debugging, or you’re debugging using browser-cached assets that are about to expire.

To solve this, you need to version your files and your source maps, either by:

  • Versioning each filename, e.g., script.abc123.min.js
  • Versioning the URL’s query string, e.g., script.min.js?abc123
  • Versioning a parent folder, e.g., abc123/script.min.js

Whichever you strategy you choose doesn’t matter, only that you use it consistently for all your JavaScript assets. It’s expected that each compiled file → source map share the same version and version scheme, like the following example:

// script.abc123.min.js
for(var a=[i=0];++i<20;a[i]=i);
//# sourceMappingURL=script.abc123.min.js.map

Versioning this way will ensure that each browser agent downloads the source map that belongs to each compiled file, avoiding version mismatches.



If you’ve read this far, you should be fairly equipped to fix source map transformations and debug like a pro. Nice work. Think of something we missed? We look forward to your email.

We also highly recommend checking out the Sentry documentation on this topic.

Source:: scotch.io

Build and Deploy a Serverless Function to Netlify

By James Quick

Recently, Netlify has become one of the most popular hosts in Web Development. Netlify offers an incredible variety of features like serverless (lambda) functions, free https certs, and more!

Since Netlify is well known for hosting static sites that don’t come with a backend, serverless functions help fill some of those gaps. In this article, we will walk through creating a serverless/lambda function, running and testing it locally, and deploying it to Netlify.

Related Reading: Deploying Your First Gatsby Site to Netlify

https://youtu.be/_1qXQM3Mt4Q

But First… What Are Lambda Functions

Serverless functions is actually the more generic term. Serverless is a misnomer, however, as it doesn’t mean there is no server at all.

It simply means you, the developer, don’t have to worry about the server.
You don’t have to create a Node server, for example, because the host takes care of all of that for you. All you have to worry about is writing the actual functionality with no regards for infrastructure, versioning, etc.

The word Lambda is a proper noun referring to the type of serverless functions that are hosted on Amazon’s AWS cloud platform. They were one of the very first ones to support/implement serverless functions, and this is the type of serverless functions that Netlify supports.

In this article serverless functions and Lambda Functions will refer to the functions that we create and host in Netlify.

Create a Serverless Function with AWS Lambda

For this demo, I am going to start with a basic Gatsby app. You don’t have to use Gatsby yourself (it really doesn’t matter what kind of site you us), but if you want to get caught up with the same starter, go back and check out Deploying Your First Gatsby Site to Netlify.

For reference, when running mine, it just looks like this.

To get started, we need to create a folder that contains all of our Lambda Functions. It doesn’t really matter where you put the folder or what you call it, but I’m going to put mine in the root of my app and call it functions.

For reference, there will be a 1:1 relationship between the files in this folder and the functions that get deployed. In other words, we will create a new JavaScript file for each function we host.
So, let’s create a “test.js” file inside of the functions directory and get started writing some code. Here’s the basic boilerplate code for a Lambda Function.

test.js

exports.handler = function(event, context, callback) {
}

Each function takes in three parameters event, context, and callback.

  • event : where we can retrieve post data, headers
  • context : information about the context in which the function was called, like certain user information
  • callback : a function that we call to return a response to the user

The first parameter that the callback function takes is an error, which is null if there is no error. If the error is present, it will be respected and handled back to the user, but if is is null, the second parameter gets returned to the user.

Here’s a screenshot of my file structure, and a simple Hello World Lambda Function. In this example, I immediately call the callback function with no error and a return data with status of 200 and body of “Hello World”.

Run a Lambda Function Locally

Now that we’ve created a Hello World function, we need to be able to run it. To do this, we will use the “netlify-lambda” package. To install, run the following command.

npm install netlify-lambda


With that package installed, the docs tell use to use the following command to run our functions locally, where refers to the directory where we have written our source code.

netlify-lambda serve <functions_directory>

However, I wasn’t able to run this command directly, so I created an alias in the package.json file, “start:lambda” to use NPM to run this command.

The last thing we need to do before we can run locally is to create a configuration file that tells Netlify where to serve our functions from. I want to be specific here, this is not the directory where we write our source code. In fact, our source code will go through a build process, and the built assets will be put in the folder that we specify. So, create a Netlify.toml file in the root of your directory that looks like this.


This tells Netlify that when our functions are built, put the built assets in a directory called “lambda”.

Now, run the npm script we defined above. Notice in the screenshot that I tried to run this command once before creating the Netlify.toml and the command failed. You have to have your Netlify.toml file created before you can run locally.

Ok, now we’ve actually got something running. From here, I’m going to open up an app called Postman (go download and install it if you haven’t already… trust me!!) to make test calls to the function (think a GUI for curl requests). With Postman open, I’ll make a call to “localhost:9000”, where lambda functions run by default locally. After making the request, I get a successful response.

We’ve got Hello World working, so let’s take it one step further. I want to give an example of extracting the post body, returning a JSON object instead of a string, and conditionally returning an error. So, I’m going to expect that calls to this function pass in an object with a name property like this.

{ "name": "James" }

To retrieve this data, originally, I thought I would just grab the body property off of the event parameter, and then the name parameter off of that…BUT, I was wrong. The body parameter is actually a string instead of an actual JSON object, so first I need to parse that JSON string into an object like this.

const parsedBody = JSON.parse(event.body);

Using ES6, I can take this one step further and grab the name property off of the parsedBody by using destructuring.

const { name } = JSON.parse(event.body);

For demo purposes, I’m going to say if the name is “James” it’s a good request, otherwise, it’s a bad request and return data or error appropriately. If the name is “James”, I want to return a json object with a msg property. When we return JSON objects, they need to be “stringified” because the body parameter will always be a string that gets returned. Will look something like this.

callback(null, {
    statusCode: 200,
    body: JSON.stringify({ msg: "Thanks for visiting " + name })
});

Otherwise, I’ll return an error.

callback(new Error("You're not James"));

The whole thing now looks like this.

Now, let’s test in Postman again. First with the successful case.

And the error case.

Deploy Serverless Function to Netlify

So far, we’ve just run our Lambda Function locally using the serve command. However, in production, we will need to run the build command, which will create the built assets that Netlify will serve up for. For this reason, I am going to create another script alias in the package.json file for building.

In Netlify, you only get one command to run when Continuous Deployment kicks in and grabs your latest code from Github. However, since I also need to build my Gatsby app, we will need two commands, one to build Gatsby and one to build your functions.

To accomplish this, I also added a prod script which will allows me to run both of theses commands sequentially.

"prod": "npm run build; npm run build:lambda",

Keep in mind, if you’re not using Gatsby you may have an alternative build command or not need one at all.

The last thing we need to do before deploying is update the Netlify.toml file. This configuration file is read by Netlify when Continuous Deployment is triggered. In this file, we can tell Netlify to run our newly created “prod” command. Configurations in this file will override existing configurations set in the Netlify UI.

After checking these updates in and pushing to my Github repository, a new build will start that you can monitor in the Deployments tab. If you click on the deployment, you can view the logs. In the screenshot below, you can see our commands being run.

After the deployment has finished, you can navigate to the Functions tab. Since we actually deployed a function, you should notice your function listed in the dashboard (test.js below).

Recap

That’s it, you should be ready to go. Keep in mind, you can be completely creative with your functions…they can do almost anything. Send an email, save data to a DB, make an API call… whatever you want. With functions under your belt, you can focus a lot on your front end (assuming you’re using a static site generator like Gatsby), and fill in your backend needs using Lambda Functions or something like Firebase.

Would love to hear in the comments about the projects you guys are working on and how working with Netlify has been for you. Feel free to comment below or reach out to me on twitter, @jamesQquick.

Resources

Source:: scotch.io

Using Create React App v2 and TypeScript

By Chris Sevilleja

Now that Create React App v2 is out, official TypeScript support comes with it. This is an exciting thing for JavaScript users that use TypeScript. TypeScript is a powerful tool that helps us write safer and self-documenting code. We can catch bugs faster with TypeScript.

Related Reading: From JavaScript to TypeScript: Types & Variables

Many people have opinions about TypeScript, good and bad, but it’s a good idea to give it a chance. Ken Wheeler did and we have this tweet now:

For this article, we’ll focus on getting a Create React App up with TypeScript and we’ll do a larger project where we use TypeScript and React together in a future article.

Starting a TypeScript Create React App

This is the easiest part!

npx create-react-app my-typescript-app --typescript

What packages does the --typescript flag get us and what changes does it make?

The TypeScript Additions

The --typescript flag will add the main TypeScript package.

We also get this notice: We detected TypeScript in your project (src/App.test.tsx) and created a tsconfig.json file for you.

The tsconfig.json file is how we configure TypeScript projects similar to how package.json is for JS projects.

tsconfig.json

The default tsconfig.json doesn’t really have much we should concern ourselves with when getting started.

{
  "compilerOptions": {
    "target": "es5",
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "preserve"
  },
  "include": ["src"]
}

The App.tsx File

Let’s jump into the main App file that usually is our main React component. You may be worried that this file is a scary looking file full of TypeScript typings. Let’s look:

App.tsx

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <p>
            Edit <code>src/App.tsx</code> and save to reload.
          </p>
          <a
            className="App-link"
            href="https://reactjs.org"
            target="_blank"
            rel="noopener noreferrer"
          >
            Learn React
          </a>
        </header>
      </div>
    );
  }
}

export default App;

Wait a minute!

It’s the same as the JavaScript App.js!

We get the same base as our JavaScript projects, but we can sprinkle TypeScript on top. Let’s create a TypeScript component and see what benefits we can gain.

Creating a TypeScript Component

We’ll start by creating a normal functional component in this same App.tsx file:

A JavaScript Component

function MyMessage({ message }) {
  return <div>i shall speak! my message is: {message}</div>;
}

A simple component where we pull message out of props. Now let’s add some TypeScript to tell this function that it’s message parameter should be a string:

Adding TypeScript

If you’re familiar with TypeScript, you may think you want to add the following to message: message: string. What we have to do in this situation is define the types for all props as an object. There’s a few ways we can do this:

Types Inline

function MyMessage({ message }: { message: string }) {
  return <div>i shall speak! my message is: {message}</div>;
}

Props Object

function MyMessage(props: { message: string }) {
  return <div>i shall speak! my message is: {props.message}</div>;
}

Separate Types Object

interface MyMessageProps {
  message: string;
}

function MyMessage({ message }: MyMessageProps) {
  return <div>i shall speak! my message is: {props.message}</div>;
}

There are many ways to use TypeScript in our projects. You can create an interface and move that into a separate file so your types can live elsewhere. This may seem like a lot of writing, so let’s see what we gain for writing a bit more.

We’ve told this component that it only accept a string as the message parameter. Now let’s try using this inside our App component.

Using TypeScript Components

Let’s use this MyMessage component.

My favorite part about TypeScript is that it let’s us write self-documenting code.

When we go to use this component, we can see VS Code bring up the component’s signature right as we type! We don’t have to jump back to the component (especially if it’s in another file) to see what its inputs should be.

Now that isn’t the most readable, so let’s jump into using each prop individually.

Seeing Prop Types

As soon as we start typing message, we can see what that prop should be:

Seeing Type Errors

If we add a number as message, TypeScript will throw an error and help us catch these typing bugs.

React won’t even compile if there are type errors like this:

Conclusion

This only scratches the surface of what TypeScript provides us. You can create types for all your components and props and with VS Code, be able to read those easily. You’ll also catch errors faster since TypeScript won’t even let the project compile with type errors.

Source:: scotch.io

4 Uses of JavaScript's Array.map() You Should Know

By William Imoh

From the classic forloop to the forEach() method, various techniques and methods used to iterate through datasets abound JavaScript. However, one of the more popular methods is the .map() method.

.map() creates an array from calling a specific function on each item in the parent array. .map() is a non-mutating method in that it creates a new array as against mutating methods which only make changes to the calling array. This can be tricky to remember.

In this post, we’ll look at 4 noteworthy uses of the .map() in JavaScript. Let’s begin!

Calling a Function on Each Item in an Array

.map() as earlier stated accepts a callback function as one of its arguments and an important parameter of that function is the current value of the item being processed by the function. This is a required parameter.
With this parameter, we can modify each individual item in an array and create a new function off it. Here’s an example:

const sweetArray = [2, 3, 4, 5, 35]
const sweeterArray = sweetArray.map(sweetItem => {
    return sweetItem * 2
})

console.log(sweeterArray) // [4, 6, 8, 10, 70]

This can even be simplified further to make it cleaner with:

// create a function to use
const makeSweeter = sweetItem => sweetItem * 2;

// we have an array
const sweetArray = [2, 3, 4, 5, 35];

// call the function we made. more readable
const sweeterArray = sweetArray.map(makeSweeter);

console.log(sweeterArray); // [4, 6, 8, 10, 70]

Having code like sweetArray.map(makeSweeter) makes that a bit more readable when you jump into this code.

Converting a String to an Array

.map() is known to belong to the Array prototype. How about we use it to convert a String to an Array. Not to worry, we are not developing the method again to work for strings rather we will use the special .call() method.

Everything in JavaScript is an object and methods are just functions attached to these objects. .call() allows us to utilize the context of one object on another. Therefore, we would be copying the context of .map() in an array over to a string.

.call() can be passed arguments of, the context to be used, and “parameters for the arguments of the original function”. Sounds like gibberish? Here’s an example.

const name = "Chuloo"
const map = Array.prototype.map

const newName = map.call(name, eachLetter => {
    return `${eachLetter}a`
})

console.log(newName) // ["Ca", "ha", "ua", "la", "oa", "oa"]

Here, we simply used the context of .map() on a String and passed an argument of the function which .map() expects. Voila! We have a wolf-lang looking characters in our console. Yikes!

This functions like the .split() method of a String only that each individual string characters can be modified before being returned in an array.

Rendering Lists in JavaScript Libraries

JavaScript libraries like React utilize .map() to render items in a list. This requires JSX syntax however as .map() method is wrapped in mustache-like JSX syntax. Here’s a good example of a React component.

import React from "react";
import ReactDOM from "react-dom";

const names = ["john", "sean", "mike", "jean", "chris"];

const NamesList = () => (
  <div>
    <ul>{names.map(name => <li key={name}> {name} </li>)}</ul>
  </div>
);

const rootElement = document.getElementById("root");
ReactDOM.render(<NamesList />, rootElement);

Are you unfamiliar with React? This is a simple stateless component in React which renders a div with a list. The individual list items are rendered using .map() to iterate over the names array initially created. This component is rendered using ReactDOM on the DOM element with id of root.

Reformatting Array Objects

How about handling objects in an array? .map() can be used to iterate through objects in an array and in a similar fashion to traditional arrays, modify the content of each individual object and return a new array. This modification is done based on what is returned in the callback function. Here’s an example:

const myUsers = [
    { name: 'chuloo', likes: 'grilled chicken' },
    { name: 'chris', likes: 'cold beer' },
    { name: 'sam', likes: 'fish biscuits' }
]

const usersByFood = myUsers.map(item => {
    const container = {};

    container[item.name] = item.likes;
    container.age = item.name.length * 10;

    return container;
})

console.log(usersByFood);
// [{chuloo: "grilled chicken", age: 60}, {chris: "cold beer", age: 50}, {sam: "fish biscuits", age: 30}]

All we did is simply modify each object in the array using the bracket and dot notation. This use case can be employed to process or condense received data before being saved or parsed on a frontend application.

Conclusion

In this post, we looked at for main uses of the .map() method in JavaScript. A thing to note is that in combination with other methods, the functionality of .map() can be extended and utilized powerfully. Try to find out more use cases. Leave your comments, questions, and feedback in the comments section, they’ll be appreciated!

Source:: scotch.io

Node.js Everywhere with Environment Variables

By John Papa

illustrated guide to using environment variables

You build your Node.js apps to work first and foremost on your computer. You know it’s important that apps also work everywhere they need to run. This could be on your colleagues’ computers, internal company servers, cloud servers, or inside of a container (maybe using Docker). Enter environment variables.

I have been a closet sketch-noter for a while now. I decided to start sharing them more. You can see the sketch-note I created for this post, as an illustrated guide to using environment variables.

Environment variables are a fundamental part of developing with Node.js, allowing your app to behave differently based on the environment you want them to run in. Wherever your app needs configuration, you use environment variables. And they’re so simple, they’re beautiful!

Read more

I wrote a post in the Node.js Collection on Medium that walks you through creating and using environment variables, leading to a Node.js app you can run anywhere. Check it out and leave a “clap” if you like it!

Source:: johnpapa