{"id":18338787,"url":"https://github.com/tableflip/meteor-sass-bootstrap4","last_synced_at":"2025-04-06T05:31:50.841Z","repository":{"id":72910854,"uuid":"53061830","full_name":"tableflip/meteor-sass-bootstrap4","owner":"tableflip","description":"Meteor 1.3 + sass + bootstrap4 the npm way.","archived":false,"fork":false,"pushed_at":"2016-03-27T08:51:32.000Z","size":25,"stargazers_count":19,"open_issues_count":3,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-21T18:02:06.067Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tableflip.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-03-03T15:35:02.000Z","updated_at":"2018-09-18T10:12:20.000Z","dependencies_parsed_at":"2023-05-26T01:15:41.406Z","dependency_job_id":null,"html_url":"https://github.com/tableflip/meteor-sass-bootstrap4","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tableflip%2Fmeteor-sass-bootstrap4","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tableflip%2Fmeteor-sass-bootstrap4/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tableflip%2Fmeteor-sass-bootstrap4/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tableflip%2Fmeteor-sass-bootstrap4/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tableflip","download_url":"https://codeload.github.com/tableflip/meteor-sass-bootstrap4/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247440346,"owners_count":20939221,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-05T20:15:24.000Z","updated_at":"2025-04-06T05:31:50.832Z","avatar_url":"https://github.com/tableflip.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Meteor 1.3 + sass + bootstrap4: the npm way.\n\n A [(╯°□°）╯︵TABLEFLIP](https://tableflip.io) side project for [● Meteor London](http://www.meetup.com/Meteor-London/)\n\n## TL;DR\n\n**Meteor 1.3 has first class npm support. [npm run scripts][5] are a simple way to add build tools to your work flow.**\n\n## Why?\n\nMeteor has core plugins for working with less \u0026 stylus. Sass support isn't as up to date. Bootstrap 4 has moved to sass. At the time of writing the Meteor scss plugin doesn't support importing files from npm _or_ meteor packages.\n\nIf you want a nice setup where you can customise the core bootstrap 4 variables and have it re-build on demand, you're either going to have to upgrade the meteor scss compiler (I spent a 4 hours on it and gave up) or find your own way.\n\nI've found [npm run scripts][5] super helpful on other projects. Setting them up to rebuild on change is painless. More importantly, there is very little magic involved so you can fit it all in your head; reuse the patterns to add other build steps; and use the knowledge on non-meteor projects too.\n\n## How?\n\nMeteor already compiles, minifies, versions and hot reloads your css files, so that's all covered. On this quest, we want to:\n\n- Depend on the bootstrap source files, in a way we can import them into our project.\n- A **build** step that'll run the sass compiler to create the css.\n- A **watch** step that'll re-build the css when we change the scss, so dev is still fun.\n- For bonus marks we'll add [autoprefixer][6], to add vendor-specific css prefixes for us.\n- Pull in the bootstrap js files, for the advanced interactions like drop-downs.\n- Grab the whole thing or have the option to whittle it down to what we use.\n- Build it all from a single command into deployable bundle.\n\n**Adventure time!** You can follow along or just check the source code in the repo to skip ahead.\n\nThis project was created by running `meteor create`\n\n```shell\nmeteor create --release 1.3-beta.12 sass-bootstrap4\n```\n\n\u003csmall\u003eThe `--release 1.3-beta.12` is used to use the latest 1.3 release before it's out of beta. \u003c/small\u003e\n\nThat scaffolds out a meteor project skeleton for us:\n\n```shell\ntree sass-bootstrap4\n.\n├── package.json\n├── sass-bootstrap4.css\n├── sass-bootstrap4.html\n├── sass-bootstrap4.js\n└── tests.js\n```\n\nNew for meteor 1.3, we get an npm package.json included as standard, like so:\n\n```json\n{\n  \"name\": \"meteor-sass-bootstrap4\",\n  \"private\": true,\n  \"version\": \"0.0.1\",\n  \"main\": \"sass-bootstrap4.js\",\n  \"scripts\": {\n    \"start\": \"meteor run\",\n    \"test\": \"meteor test-app --driver-package practicalmeteor:mocha\"\n  },\n  \"dependencies\": {\n    \"meteor-node-stubs\": \"~0.2.0\"\n  }\n}\n```\n\nIt includes some scripts for `start` and `test` already which is interesting... we'll circle back to them in a minute...\n\n---\n\nStaying on the bleeding edge is a full time job, so let's add `bootstrap4-alpha`, via npm (I'm using `v3.7.5` according to my `npm -v`)\n\n```shell\n# Get all the existing deps listed in the package.json\nnpm install\n\n# Add bootstrap, scss files and all.\nnpm install --save bootstrap@4.0.0-alpha.2\n```\n\nNow we've got a `node_modules` directory for our npm packages. In it, a `bootstrap` directory filled with the latest release\n\n```shell\n$ tree -L 3\n.\n├── README.md\n├── node_modules\n│   ├── bootstrap\n│   │   ├── CHANGELOG.md\n│   │   ├── LICENSE\n│   │   ├── dist\n│   │   ├── package.json\n│   │   └── scss\n```\n\nNow try the `start` script from earlier\n\n```shell\nnpm start\n```\n\nWe see the familiar meteor launch sequence, _but why would you use npm start instead of just `meteor run`?_\n\nEither is fine. An **npm run script** is just an command alias you can configure easily from your package.json.\n\n```json\n  \"scripts\": {\n    \"start\": \"meteor run\",\n    \"test\": \"meteor test-app --driver-package practicalmeteor:mocha\"\n  }\n```\n\nHere, `npm start` is an alias for `meteor run`. Now check out the `test` script. That thing is remembering command line arguments for us. As soon as you need to pass a `--settings settings.json` to your app, you'll find a short cut like `npm start` a helpful way to save a few key strokes.\n\n```\n\"scripts\": {\n  \"start\": \"meteor run --settings settings.json\"\n```\n\nThe app should be up and running, go check it out... http://localhost:3000 in your navigator of choice.\n\n---\n\n![Meteor 1.3 default app screenshot][1]\n\nIt's not shiny yet. Bootstrap is still all in the node_modules folder where we left it. npm modules don't care about your needs. (npm \u003c3s you, but that's cos they have intense feels and a wombat.)\n\n![npm wombat][2]\n\n**Tuck your brain in and put your safety goggles on. We are now going to make it work.**\n\n## build:css\n\nUpgrade the css to a scss file called `main.scss`. In it, we'll override a variable, and then import the all the bootstrap styles:\n\n**main.scss**\n\n```scss\n$body-bg: hotpink;\n@import 'bootstrap/scss/bootstrap';\n```\n\nInstall the npm dependency `node-sass`, so we can call on it to compile things.\n\n```shell\nnpm install --save node-sass\n```\n\nand in `package.json` add a `build:css` script:\n\n```json\n\"scripts\": {\n  \"start\": \"meteor run\",\n  \"test\": \"meteor test-app --driver-package practicalmeteor:mocha\",\n  \"build:css\": \"node-sass --include-path node_modules main.scss bundle.css\"\n}\n```\n\nBy adding `--include-path node_modules` we configure node-sass to check the node_modules dir when it encounters an `@import` statement. Open a new terminal, and run `build:css`\n\n```shell\n$ npm run build:css\n\n\u003e sass-bootstrap4@0.0.1 build:css /Users/oli/Code/tableflip/meteor-sass-bootstrap4\n\u003e node-sass --include-path node_modules main.scss bundle.css\n\nRendering Complete, saving .css file...\nWrote CSS to /Users/oli/Code/tableflip/meteor-sass-bootstrap4/bundle.css\n```\n\n![][4]\n\n:tada: SUCCESS! The tell-tale bootstrap font-stack is evident and our body background color is hotpink.\n\nWe have a `bundle.css` that is derived from our `main.scss`. Add `bundle.css` to your `.gitignore` file.\n\nThe css file it gets picked up by the regular meteor build pipeline, versioned and hot-reloaded. But if we edit the .scss file nothing happens. Nothing is watching our main.scss for edits...\n\n\u003e Once you have an npm run sript, every problem looks like an npm run script problem.\n\n\u003csmall\u003e_@olizilla_ 3rd March 2016\u003c/small\u003e\n\n## watch:css\n\n[`nodemon`][6] is the tool of choice for running commands when a file changes.\n\n```shell\nnpm install --save-dev nodemon\n```\n\nWe'll use it to add the `watch:css` script\n\n```json\n\"scripts\": {\n  \"start\": \"meteor run\",\n  \"test\": \"meteor test-app --driver-package practicalmeteor:mocha\",\n  \"build:css\": \"node-sass --include-path node_modules main.scss bundle.css\",\n  \"watch:css\": \"nodemon -e scss -x npm run build:css\"\n}\n```\n\nWhere:\n- `nodemon`: watch for changes in the current directory...\n- `-e scss`: in files with the `scss` extension...\n- `-x npm run build:css`: execute `build:css` on change.\n\n\nnow we can run the project and auto-build the css on change with _just_ a\n\n```\nnpm build:css\nnpm start\nnpm watch:css\n```\n\n...But that is far too much faff. Let's iterate.\n\n## npm-run-all\n\nWhen you want to run multiple steps sequentially, or in parallel from a single script, [`npm-run-all`][7] is your friend\n\n```sh\nnpm install --save-dev npm-run-all\n```\n\n```json\n\"scripts\": {\n  \"start\": \"npm-run-all build:* --parallel watch:* meteor\",\n  \"meteor\": \"meteor run\",\n  \"test\": \"meteor test-app --driver-package practicalmeteor:mocha\",\n  \"build:css\": \"node-sass --include-path node_modules main.scss bundle.css\",\n  \"watch:css\": \"nodemon -w client -e scss -x npm run build:css\"\n}\n```\n\nThe `meteor` script is now an alias for `meteor run`.\n\n`start` maps to `npm-run-all build:* --parallel watch:* meteor`, which translates to:\n\n\u003e \"run all the scripts that start with `build:` in sequence. When they complete, run in `parallel` the `watch:` scripts and the `meteor` script.\n\nNow you can build the scss into css, re-build on change, and run the meteor dev server all in one `npm start`.\n\n**As an aside, if you find yourself running lots of npm scripts, you may find the [ns][9] tool rather handy.**\n\n## autoprefixer\n\nbootstrap 4 assumes you will use [autoprefixer][8] to add vendor specific css aliases, so let's add it\n\n```shell\nnpm install --save-dev postcss-cli autoprefixer\n```\n\n```json\n\"scripts\": {\n\n  \"build:css\": \"node-sass --include-path node_modules main.scss | postcss --local-plugins --use autoprefixer --output bundle.css\"\n}\n```\n\nThis looks complicated, but it breaks down into two parts\n\n- `node-sass --include-path node_modules main.scss |` is the same as before, but now we pipe the output to the next command rather than `bundle.css`.\n- `postcss --local-plugins --use autoprefixer --output bundle.css` is new, and takes the css piped in, runs autoprefixer on it, and output the result to `bundle.css`\n\nThe `--use` is where you can include any other plugins from the PostCSS universe that you might find useful too: https://github.com/postcss/postcss#plugins\n\nWith that in place, running `build:css` now outputs customised bootstrap css, with vendor prefixes based on the current recommendations from http://caniuse.com\n\n## require('bootstrap')\n\nTo make **all** the Bootstrap javascript plugins available to your app, create a `client/lib/bootstrap/plugins.js` file.\n\n```js\n/*\nI load up the requried bootstrap plugins, from `node_modules/bootstrap`\n*/\nTether = require('tether')\nrequire('bootstrap')\n```\n\nyou'll also need to install the tether module, as the tooltip component uses it\n\n```shell\nnpm install tether\n```\n\nYour client app will now be able to use toggle buttons, modals, and all the fancy js dependent components.\n\n## Production build\n\nthe `meteor` build tool isn't aware or sass build step, so we need to make sure the css is built before creating a deployable bundle. `npm-run-all` comes in handy again:\n\n```\n\"scripts\": {\n\n  \"meteor:build\": \"meteor build\",\n  \"deploy\": \"npm-run-all build:* meteor:build\",\n}\n```\n\n`deploy` run all our `build:` steps, then runs `meteor:build` to create the deployable production bundle. There are plenty of arguments you might want to add to that step, which you can find by running `meteor help build`\n\n## Optimise\n\nYou can later optimise your build to only include the components you use, by being more specific with your `require`.\n\n```js\nrequire('bootstrap/dist/umd/alert.js')\nrequire('bootstrap/dist/umd/button.js')\n```\n\nwould add just the `alert` and `button` components to be added to your js bundle. We no longer need the tether dependency as `tooltip` isn't required.\n\nYou can do a similar thing in your `main.scss`\n\n```scss\n// Get the basics\n@import \"bootsrap/scss/variables\";\n@import \"bootsrap/scss/mixins/hover\";\n@import \"bootsrap/scss/mixins/tab-focus\";\n@import \"normalize\";\n@import \"reboot\";\n\n// get specific bootstrap components\n@import \"bootsrap/scss/_alert\"\n@import \"bootsrap/scss/_button\"\n```\n\nBecause we built the bootstrap integration ourselves, it was easier to figure out how to extend it, what parts are optional, and what we can change later.\n\nWe control the versions of node-sass and bootstrap we use, so we can get as close to the bleeding edge as we're comfortable with. Using stable releases would work just as well.\n\nMeteor packages can do a lot of work for you, adding UI widgets and data sync options, but if sass and bootstrap are going to be the core of your UI, then it can be a confidence boost to remove some of the magic and get a little more control over the integration.\n\n---\n\nA [(╯°□°）╯︵TABLEFLIP](https://tableflip.io) side project for [● Meteor London](http://www.meetup.com/Meteor-London/)\n\n\n[1]:https://cloud.githubusercontent.com/assets/58871/13501269/e2403c16-e15d-11e5-9ca0-ae5a73bb47d3.png\n[2]:http://36.media.tumblr.com/1e63026e4211a6e7711fe95d5ff6b13e/tumblr_inline_nn489p271Z1t68bpr_500.png\n[3]:http://wp.production.patheos.com/blogs/friendlyatheist/files/im/qiaVKwS.png\n[4]:https://cloud.githubusercontent.com/assets/58871/13575136/229930dc-e47f-11e5-8d45-9f96d72123f8.png\n[5]:http://blog.npmjs.org/post/118810260230/building-a-simple-command-line-tool-with-npm\n[6]:https://github.com/remy/nodemon#nodemon\n[7]:https://github.com/mysticatea/npm-run-all#npm-run-all\n[8]:https://github.com/postcss/autoprefixer\n[9]:https://github.com/knownasilya/npm-scripts\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftableflip%2Fmeteor-sass-bootstrap4","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftableflip%2Fmeteor-sass-bootstrap4","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftableflip%2Fmeteor-sass-bootstrap4/lists"}