Skip to content

Major Project Restructure and efficiency related changes#2083

Closed
menasheh wants to merge 8 commits intojmoenig:masterfrom
menasheh:master
Closed

Major Project Restructure and efficiency related changes#2083
menasheh wants to merge 8 commits intojmoenig:masterfrom
menasheh:master

Conversation

@menasheh
Copy link

Introduction

Snap! is a repository of massive javascript files. According to codeclimate, it's "maintainability" is two years, with over 1000 code smell issues and 600 duplication issues (probably translation files). I want to do to snap something similar to what I did to morphic in effort to make it a more enjoyable codebase to work with, and to make it more extensible.

Goals

Personally, I want to make a block-based programming environment for TI calculators. I'm sure there are other people with other use case ideas as well. Technically, I could just fork now and do my own thing from here on. However, I want my project to be able to benefit from future improvements to Snap! without my manually copying code from Snap's several thousand line files to the smaller ones I'd break them down into in effort to both make the project more maintainable and learn about all of it's pieces. If Snap! were a little more modular, with some of the different pieces in different repositories, each published as npm packages and used as dependencies within the other projects as appropriate, that would make it much easier to make another project extending only certain parts of snap and not others. It also makes sense to give back to the Snap! codebase, as it will be a giant upon which my project will stand to reach further. So I'm focusing on things which will benefit both projects first, by trying to make the base project more extensible and maintainable.

For maintainability, I'd want to separate each library into different files and bundle them all together to create the final product, a single file, snap.min.js. It's a bit complicated, so I'll discuss this more amongst the changes.

Changes

Here's what's been changed so far in this PR:

Project Structure

Everything in the top level directory of a project leads to a big mess of files, especially with all the lang-*.js files. It was hard to find what you're looking for in that awesome pile of code. Here's my proposed system:
docs folder for documentation and help, as well as assorted .txt files that found their way into the repo.
dist folder for generated files such as snap.js, snap.min.js
media folder for libs, examples, sounds, and other media
src folder for source
src/lang folder for language files
package.json for package configuration (see Package Management)
gulpfile.js for managing build scripts. (See Build Tool)

Package Management

Morphic.js has it's own repository, so why should its code be duplicated in this one? We can solve this redundancy problem by using npm, the node package manager. If you don't already have nodejs and npm, you can download them here. (npm comes with nodejs.) From what I understand, these tools are ubiquitous in the javascript development world. In package.json we include morphic-gui and filesaver as dependencies. We can get rid of those respective files in snap's source control, but download them and store them in the gitignored node_modules folder automatically by using npm install in Snap!'s main directory. There might be more modules we could use. The sha512, for example, seems to be from another module, but I don't think the currently available module necessarily supports the same functions in the one Snap has.

Build Tool

Prior to this PR, snap's main file made 16 javascript requests to load each of the javascript files.
I chose gulp as a build tool for the project. Although webpack seems to be a favorite for a lot of people, it is a module bundler first and a build tool second. I didn't want the webpack wrapper around the files, I just want to concatenate files together and minify the output. I was unable to get webpack to do that, and able to get gulp to do that.

To use gulp, you need to have NodeJS installed. Run npm i -g gulp-cli anywhere and npm i in this project directory.
With the tasks I defined in gulpfile.js, we're able to accomplish various tasks:

  • gulp scripts will build snap.js, snap.min.js, and snap.min.js.map and put them in the dist folder.
  • gulp images will minify any image files found in or under the media folder.
  • gulp lint will run jshint on our code. (It's another javascript linter, it has a lot of output at the moment.)
  • gulp watch will watch the src files for changes and run gulp scripts any time they are changed.

And there are tons more possibilities on that front. For example, we could add automatic browser reloading when code is changed, some form of unit tests, or a translation-related script, to the gulpfile in the future.

The method of getting the required dependencies included in the file generated by gulp is a working but slightly messy method, as it lists each file specifically in order in the gulpfile, even for dependencies such as morphic.js. But, it works.

Other efficiency changes

  • index.html was an empty page redirecting to snap.html. I thought that was inefficient, so I renamed snap.html to index.html.
  • Images have been minified with imagemin (through gulp images task). That saved around 20% of the space the example images were occupying.
  • Tools.xml was duplicated in the main folder. I deleted it, and rerouted the Import tools menu option to use the equivalent file in media/libs

Hope this helps!

@cycomachead
Copy link
Collaborator

Following the discussion in #1863, I'm going to close this. While I very much love directories and smaller files, others don't have an interest in that right now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants