Giter Site home page Giter Site logo

static-asset-service's Introduction

Static Asset Service

This repository provides tools to generate and upload to S3 the asset files used by a static asset service. Such a service can be used by client applications to share Javascript assets in an organized, declarative way, and thus reduce the overall page size and number of requests when multiple applications coexist on the same page.

Overview

This repository provides the tools for generating combined and compiled asset files from base assets, and then deploying the files to S3 so that they can be consumed by applications using the static asset loader client.

The example Assets illustrate the form required for assets that the service provides.

The static asset client used to require and define assets in a Javascript client application is not included in this repository, but is rather a part of bv-ui-core.

Generating Static Asset Files

To generate the asset files:

var staticAssetService = require('static-asset-service');

staticAssetService.generate({
  // The namespace that apps consuming these generated assets will use.
  namespaceName: 'BV',

  // The directory where the generator can expect to find the asset files.
  sourceDir: '/path/to/assets',

  // The destination where the assets will be created.
  targetDir: '/path/to/dist',

  // If true, minify the generated outputs using uglify.
  uglify: true,

  // If true, log progress to the console.
  log: true,

  // List the asset bundles that need to be supported for each application using
  // this service. The generator will only generate combination files for these
  // listed assets.
  //
  // We constrain the asset generation in this way for combinatorial reasons -
  // creating static combinations gets large rapidly. Ten assets combine to
  // more than 1000 files even with alphanumeric ordering of names enforced, but
  // four or less is managable.
  //
  // Each asset must have a corresponding file in the assets directory. For
  // example, for the asset [email protected], there must be a file
  // assets/jquery-example/1.11.1.js.
  //
  // IMPORTANT: assets MUST be listed in dependency order, i.e. the order in
  // which they must load to satisfy one another.
  assetBundles: {
    firebird: [
      '[email protected]',
      '[email protected]',
      '[email protected]'
    ],
    curations: [
      '[email protected]',
      '[email protected]'
    ],
    spotlights: [
      '[email protected]',
      '[email protected]'
    ]
  }
}, function (error) {
  if (error) {
    console.error('Generation failed.', error);
  }
  else {
    console.info('Generation complete.');
  }
});

About the Namespace

The static asset service requires a global namespace - that is, a property on window - that it can use to communicate back to the apps that request assets. When generating files, this namespace needs to be known in order to properly provide the individual assets to the requesting application.

In browser applications, the namespace is generated by the bv-ui-core namespacer module.

Uploading Generated Files to S3

To upload the generated asset files to an S3 bucket:

var staticAssetService = require('static-asset-service');

staticAssetService.deployToS3({
  // Upload assets to this S3 bucket.
  bucket: 'example',

  // The prefix put in place for the keys of the uploaded files.
  keyPrefix: 'example/assets/'

  // If true, log progress to the console.
  log: true,

  // Optionally, specify configuration for the aws-sdk client instance. This is
  // not recommended. For preference configure S3 access using the other options
  // that do not require configuration changes in code: environment variables,
  // EC2 instance roles, etc.
  // s3ClientConfig: {
  //   accessKeyId: 'akid',
  //   secretAccessKey: 'secret',
  //   region: 'us-east-1'
  // },

  // The absolute path to the generated asset files.
  sourceDir: '/path/to/dist',

  // A semver version for your assets. Assets will be uploaded to multiple
  // locations in the bucket determined by the version and keyPrefix:
  //
  // example/assets/1
  // example/assets/1.0
  // example/assets/1.0.0
  version: '1.0.0'
}, function (error) {
  if (error) {
    console.error('Deployment failed.', error);
  }
  else {
    console.info('Deployment complete.');
  }
});

Creating Asset Files

Example Assets

The example-assets directory contains a selection of example assets that could be provided by a static asset service. The file names and contents have a few restrictions, outlined here.

File Names

Asset files must have names in the format: <resource>@<version>.js.

File Contents

Asset files should contain valid JavaScript, structured as follows so that the define function is invoked as define(assetName, asset). The asset code is wrapped in a closure to ensure that different versions can be loaded and used if necessary.

define('<resource>@<version>', (function () {

  // ...

  return resource;
})());

Development

Getting Started

Developers should run npm install before doing any work on this repository. This will install the project dependencies, as well as a pre-push hook.

Running the Tests

grunt test will run the browser tests using PhantomJS, as well as ESLint and the tests of the generator code.

grunt serve will open a browser to show the browser tests.

static-asset-service's People

Contributors

aterranova-bv avatar reason-bv avatar rmurphey avatar robbytx avatar saisuresh-sakthivel avatar sirugh avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

static-asset-service's Issues

Update for new static asset loader client model

Currently the static asset loader client in bv-ui-core (https://github.com/bazaarvoice/bv-ui-core/tree/master/lib/staticAssetLoader) is dumb: it doesn't understand dependencies, and doesn't want assets using the old define(name, dependencies, asset) signature. The idea here is that clients explicitly state all dependencies they require, and the list is winnowed prior to any request being sent given what is already available.

The generator does need to understand dependencies because asset packages are named / required in alphanumeric order - [email protected][email protected] regardless of the order they should be loaded in because of dependencies.

So the present code needs some work. I propose:

  • a metadata JSON file per asset to include dependency information.
  • the generator uses that information to order and arrange the contents of the generated files.

It is an open question as to whether the generator should include unrequested dependencies. I'm inclined to think it should not based on the present model for the client, which is to require everything you want in one lump, and that gets whittled down prior to the request being made. If the objective is to suppress the loading of assets twice, then including dependencies not explicitly required seems the wrong way to go.

Deploy to prod

Firebird is finally ready to start using the static asset service.
However, we'll need the static assets deployed to prod before we can release it.

Are we ready to deploy these files to prod ?

Deployment should not fail if sourcemaps aren't present

In the case where assets are not minified, no sourcemaps will be present in the destination directory. Currently, the deployment task throws an error if there are no sourcemaps which makes it impossible to deploy an unminified asset.

Move SDK to bv-ui-core

The SDK (https://github.com/bazaarvoice/static-asset-service/blob/master/sdk/index.js) of this could very likely have value beyond BV, and has no secret sauce -- it is essentially Yet Another Script Loader, created for the specific purpose of sharing vendor files across applications on the same page. Putting it in bv-ui-core would make it even more trivial for third-party JS applications at BV to include the SDK in their scout file.

Per discussion with @reason-bv, we should take the SDK, extract the BV-specific pieces, and ship it with the rest of bv-ui-core. This would also allow us to make the dependency on the JS loader in bv-ui-core more explicit than it is now.

Finally, this would require some minor documentation additions, such as explaining how to create a file that can be used by the static asset service.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.