npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

grunt-extjs-dependencies-wombleton

v0.2.3

Published

Uses static analysis to figure out in what order to load your ExtJs app files.

Downloads

6

Readme

grunt-extjs-dependencies

Uses static analysis to figure out in what order to load your ExtJs app files.

Getting Started

This plugin requires Grunt ~0.4.1

If you haven't used Grunt before, be sure to check out the Getting Started guide, as it explains how to create a Gruntfile as well as install and use Grunt plugins. Once you're familiar with that process, you may install this plugin with this command:

npm install grunt-extjs-dependencies --save-dev

Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript:

grunt.loadNpmTasks('grunt-extjs-dependencies');

The "extjs_dependencies" task

Overview

The task scans files for Ext.define calls (as well as some other things), parses out dependencies and saves a copy of each file with any requires: [...] removed in a temp dir.

Paths will be preserved in the temp output, based on rootDir and realtive paths in src.

Make sure classes and dependencies are defined and declared in a manner the task understands, or bad things will happen! Read more below.

After the task has run, extjs_dependencies_{TARGET NAME} will contain the list of ordered dependencies. This can then be passed to concat, uglify, etc. See example below.

In your project's Gruntfile, add a section named extjs_dependencies to the data object passed into grunt.initConfig().

grunt.initConfig({
  extjs_dependencies: {
    options: {
      rootDir: 'path/to/js/project',
      src: [{ path: 'vendor/', parse: false }, 'app/'],
      excludeClasses: ['Ext.*', 'MyApp.some.Class'],
      skipParse: ['**/app/ux/SkipMe.js'],
      resolveFrom: 'MyApp.js'
    }
  },
})

Options

options.rootDir

Type: String Default value: process.cwd()

Sets the project root. This is used to calculate realtive paths when copying stripped files to the temp dir.

options.src

Type: Array

These paths will be added to the "classpath", meaning all contained files will be scanned for ExtJs class definitions, unless the parse: false option is passed.

Paths can be passed either as strings or as objects containing a path property and a parse boolean, indicating wether or not the task should try to extract class data from the contained files. Set this to false when adding non-Ext files to the classpath.

options.excludeClasses

Type: Array Default: ['Ext.*']

Array of minimatch patterns. Any found class names matching any of these patterns will be excluded from the classpath.

The default value excludes all Ext classes, since the task is biased towards loading e pre-build version of Ext (e.g. from Sencha's CDN).

options.skipParse

Type: Array Default: []

Array of file glob patterns. Any files matching any of these patterns will be excluded.

By default no files are excluded.

options.resolveFrom

Type: String|Array

One or more file or class names, or paths, from where to begin resolving depencies. This should probably be your app's entry point (e.g. App.js).

Usage Examples

Default Options

The config below will add all JavaScript files in ./test/data/vendor and ./test/data/app to the classpath. Files under ./test/data/vendor will not be parsed.

All Ext classes will be excluded, as well as the exact class MyApp.mixin.Bar.

Dependencies will be resolved from MyApp.js. extjs_dependencies_dist will contain the ordered dependency list, which can be passed to other tasks (e.g. concat).

grunt.initConfig({
  extjs_dependencies: {
    dist: {
      options: {
        rootDir: './test/data',
        src: [{ path: 'vendor/', parse: false }, 'app/'],
        excludeClasses: ['Ext.*', 'MyApp.mixin.Bar'],
        resolveFrom: 'MyApp.js'
      }
    }
  },

  concat: {
    dist: {
      src: ['<%= extjs_dependencies_dist %>'],
      dest: 'dist/app.js'
    }
  }
})

Details

Classes are exptected to be defined using

Ext.define('MyApp.package.ClassName', { /* Class def */ })

Alternate class names are accepted via any of these methods

alternateClassName: ['OtherClassName', 'ThisIsTheSameClass']

alternateClassName: 'OtherClassName'

//@alternateClassName MyApp.ShortHandClassName

Dependencies are calculated by looking for any of these comments and annotations:

//@require MyApp.ClassName or path/to/file

requires: ['MyApp.ClassName']

extend: 'MyApp.SuperClassName'

mixins: ['MyApp.MixinA', 'MyApp.MixinB'] or { mixina: 'MyApp.MixinA', mixinb: 'MyApp.MixinB' }

In other words, ~~uses, views, models, controllers, stores~~ is not supported. As of 0.2.2 uses, views, models, controllers are stores supported. And for sanity and simplicity, why not just stick to this pattern

Ext.define('MyApp.tools.Sport', {
  extend: 'MyApp.tools.Base',
  requires: ['MyApp.util.Knife', 'MyApp.service.Spoon']
});

Note: Running it against the ExtJs source does currently not work. This is because the dependency order in the ExtJs library relies on tags/annotations (e.g. @tag) other than the ones used in most ExtJs projects (e.g. requires: […], @require). One solution is to use this module on your own project JS, and then include a suitable minified version of ext-all.js, either self-served or via a CDN. This is not optimal but also not a prioritized problem to solve.

Contributing

In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using Grunt.

TODO

  • Use more of grunt's built-in file utils
  • Fake ~~Ext.define and simply pick property values from input OR~~ walk AST top down (reverse falafel)
  • include/exclude patterns
  • Extract script tags from HTML, and maybe replace them with URL of concatenated files