Migrate from Bower to Yarn

Hey Roots Community!

I’ve been using Sage 8 as per documentation with Bower, but I would like to start making use of Yarn instead as Bower seems to be pretty outdated now. Is there a guide that will help me migrate my current project from Bower to Yarn or does it make more sense to just create a new project with Sage 9 for compatibility with Yarn?

Thanks, I appreciate any answers!

Yarn is just a npm client, so you mean migrating from Bower to npm :wink:

Sage 8’s build setup only supports Bower and the other methods available via asset-builder. If you want to import dependencies via npm you’ll need to use Sage 9.

1 Like

Thank you for the clarification @ben :smiley:

@ben is this still true? Bower has all but lost support, most projects are no longer maintaining private bower repositories, and for almost a year now bower.io themselves have been urging people to make the transition to npm/yarn.

Considering there’s no clear migration doc from sage 8.x to 9 (and even if there was, many of the people who built their sites with 8x are wholly overwhelmed by blade), itd be nice to know there’s a path forward that doesn’t require us completely redeveloping our themes.

1 Like

I think it is a good idea to move dependencies from bower to npm as we already use npm for dev dependencies. Bower just seems like a unnecessary step at this point. Here are the changes I did when testing this out on a fresh sage 8 install.

Remove dependecies from bower.json

{
  "name": "sage",
  "homepage": "https://roots.io/sage/",
  "authors": [
    "Ben Word <ben@benword.com>"
  ],
  "license": "MIT",
  "private": true
}

Add dependecies and remove wiredep devDependencies from package.json (Here I also updated all dev dependencies) and remove bower from the “scripts”.

{
  "name": "sage",
  "version": "8.5.4",
  "author": "Ben Word <ben@benword.com>",
  "homepage": "https://roots.io/sage/",
  "private": true,
  "repository": {
    "type": "git",
    "url": "git://github.com/roots/sage.git"
  },
  "bugs": {
    "url": "https://github.com/roots/sage/issues"
  },
  "licenses": [
    {
      "type": "MIT",
      "url": "http://opensource.org/licenses/MIT"
    }
  ],
  "scripts": {
    "build": "gulp",
    "start": "gulp watch",
    "jshint": "gulp jshint",
    "jscs": "jscs gulpfile.js assets/scripts/*.js"
  },
  "engines": {
    "node": ">= 4.5"
  },
  "dependencies": {
    "bootstrap": "v4.1.0",
    "jquery": "^3.3.1"
  },
  "devDependencies": {
    "asset-builder": "^1.1.0",
    "browser-sync": "^2.23.7",
    "del": "^3.0.0",
    "gulp": "^3.9.1",
    "gulp-autoprefixer": "^5.0.0",
    "gulp-changed": "^3.2.0",
    "gulp-concat": "^2.6.1",
    "gulp-cssnano": "^2.1.3",
    "gulp-flatten": "0.4.0",
    "gulp-if": "^2.0.2",
    "gulp-imagemin": "^4.1.0",
    "gulp-jshint": "^2.1.0",
    "gulp-less": "^4.0.0",
    "gulp-plumber": "^1.2.0",
    "gulp-rename": "^1.2.2",
    "gulp-rev": "^8.1.1",
    "gulp-sass": "^4.0.1",
    "gulp-sourcemaps": "^2.6.4",
    "gulp-uglify": "^3.0.0",
    "imagemin-pngcrush": "^5.1.0",
    "jshint": "^2.9.5",
    "jshint-stylish": "^2.2.1",
    "lazypipe": "^1.0.1",
    "merge-stream": "^1.0.1",
    "minimist": "^1.2.0",
    "run-sequence": "^2.2.1",
    "traverse": "^0.6.6"
  }
}

Change .bowerrc (This way we pretend to use bower to make the build process happy)

{
  "directory": "node_modules"
}

Then in gulpfile.js we can remove this part

// ### Wiredep
// `gulp wiredep` - Automatically inject Less and Sass Bower dependencies. See
// https://github.com/taptapship/wiredep
gulp.task('wiredep', function() {
  var wiredep = require('wiredep').stream;
  return gulp.src(project.css)
    .pipe(wiredep())
    .pipe(changed(path.source + 'styles', {
      hasChanged: changed.compareSha1Digest
    }))
    .pipe(gulp.dest(path.source + 'styles'));
});

and remove wiredep from the styles task so it looks like this:

// ### Styles
// `gulp styles` - Compiles, combines, and optimizes project CSS.
// By default this task will only log a warning if a precompiler error is
// raised. If the `--production` flag is set: this task will fail outright.
gulp.task('styles', function() {
  var merged = merge();
  manifest.forEachDependency('css', function(dep) {
    var cssTasksInstance = cssTasks(dep.name);
    if (!enabled.failStyleTask) {
      cssTasksInstance.on('error', function(err) {
        console.error(err.message);
        this.emit('end');
      });
    }
    merged.add(gulp.src(dep.globs, {base: 'styles'})
      .pipe(plumber({errorHandler: onError}))
      .pipe(cssTasksInstance));
  });
  return merged
    .pipe(writeToManifest('styles'));
});

Manually add bootstrap styles in main.scss as they are no longer automatically added.

@import "common/variables";

@import "./../../node_modules/bootstrap/scss/bootstrap";

@import "common/global";
@import "components/buttons";
@import "components/comments";
@import "components/forms";
@import "components/grid";
@import "components/wp-classes";
@import "layouts/header";
@import "layouts/sidebar";
@import "layouts/footer";
@import "layouts/pages";
@import "layouts/posts";
@import "layouts/tinymce";

Change assets/manifest.json to no longer depend on bower to locate files

{
  "dependencies": {
    "main.js": {
      "files": [
        "./../node_modules/bootstrap/dist/js/bootstrap.js",
        "scripts/main.js"
      ]
    },
    "main.css": {
      "files": [
        "styles/main.scss"
      ]
    },
    "customizer.js": {
      "files": [
        "scripts/customizer.js"
      ]
    },
    "jquery.js": {
      "files": [
        "./../node_modules/jquery/dist/jquery.js"
      ]
    }
  },
  "config": {
    "devUrl": "http://example.test"
  }
}

I also added a .jshintignore file to remove warnings about bootstrap

node_modules
2 Likes

There are no migration docs for anything to do with Sage because it’s a starter theme

If you’re not wanting to use Blade (or simply use PHP instead of it, because it’s also supported…) then Sage 9 isn’t really an option for you. Sage has always been about moving forward. From no build script, to Grunt, to gulp, to Webpack, to implementing things like Blade… we can’t make everyone happy. There are many people who built their sites with 8x that are wholly appreciative of Blade :wink:

Completely redeveloping your theme is what has always been recommended if you’re wanting to “upgrade” your version of Sage. Again, Sage is a starter theme and not a framework :slight_smile:

@ben
Thanks for the quick reply.
You seemed to have missed my point, though, and I’m sorry if I made you defensive.

Ideally, everyone who made a theme based on 8.x could happily continue to use their theme, make changes when necessary, and take advantage of the amazing build processes.
However, due to the growing number of developers choosing to release their code as npm repositories (in place of bower repositories, or even git), releasing updates to a Sage 8.x based theme is not always an easy option. Most recent example I came across (but not the only one) is FontAwesome 5 Pro.
That leaves people like me in a lurch, having to choose between either redeveloping the theme from scratch (be it with Sage 9 or not), or chance being stuck with outdated (potentially vulnerable) dependencies.

I wasn’t asking for a migration doc, just stressing that even redeveloping a theme with Sage 9 (to get access to all the new build tools) is a whole endeavor - getting used to a new folder structure, learn blade, when the only pressing issue we’re desperate to solve is replacing bower.

And forget ‘migration docs’, there’s no workflow comparison between 8x and 9 (to ease the development transition for loyal Sage users). And, despite all the one-liners about ‘simply using php instead’ of blade - here, the Release Announcement Post, and the sole thread on the discourse - there isn’t any info out there on how to to do that (where should I ‘copy over the templates from Sage 8’, what Sage 9 functions do I need to edit/delete, etc).

tl;dr: Don’t get me wrong, I’d love to take the time to redevelop my theme, learn blade, and adopt Sage 9 for my wordpress theming needs. But in the short term, bower’s becoming more problematic each day, and we don’t have the time and resources for a full theme rewrite, when we can (theoretically) just swap bower out for NPM.

1 Like

@KimH: Thanks for the detailed step-by-step! This is exactly what I was looking for :slight_smile:

PS: Did you try replacing wiredep with npm-wiredep before opting to strip it out entirely?

People who have made themes based on 8.x can happily continue to use their theme, make changes when necessary, and take advantage of the amazing build processes.

Install a compatible version of Node, install the dependencies, and you’re good.

Updating a Sage 8.x theme usually would mean not bumping major versions for the software that’s used in the theme, …no? I don’t understand why someone who would have a Sage 8 based theme that needed to update a minor version of a dependency would suddenly lose Bower support for whatever dependency, but, that’s not really an issue with Sage 8.

Learning anything new is a ‘whole endeavor’

What exactly are you looking for? What is missing from the Sage 9 announcement post or the changelog?

Doesn’t sound like you’ve tried anything yet. You literally just use PHP.

tl;dr - Doesn’t make any sense to want to replace Bower with npm on existing Sage 8 themes that you are simply maintaining

I swear I’m not trying to be difficult or antagonistic. I feel like I’m wasting your time, and that really wasnt my intent. :confused:

Simple real-world example. I want to update Fontawesome from v5 to v5 Pro, but its only offered as an NPM private repository (since its not worth it for them to create one for bower). That’s not reason enough to do a full redevelop of my theme.
Similarly, my theme has 3 other dependencies with small security vulnerabilities, but the devs are no longer providing bower repos. And the trend of non-git dependencies that have no bower repo is going to keep growing.

And its (theoretically) a lot faster to move the bower dependencies over to NPM so I can continue to update them, then it is to completely rewrite the theme from the scratch. Lucky for me, @KimH outlined how she did it, so I’m going to take a stab. All is good in the world :sunglasses:

Correct. While Sage 9 was exciting when it launched, I havnt had any real free time to play around with it. Then I ran into this bower issue, started doing research on how to migrate to NPM, and saw your comment from January that people who want to use NPM need to switch to Sage 9.

So, I started looking over the documentation (trying to grok the new folder structure, build process, blade templates and controllers, and searching the forum/stackexchange/github to see if there was an easier way to make the transition to v9. Meanwhile you responded to my post.

From the announcement post: “Currently, you can opt-out of Blade templates by replacing them with regular PHP ones (you could copy over the templates from Sage 8 if you really wanted to).”

This is the part I was stuck on (and would have been a new thread, if you/kim hadnt responded here).

Does this mean pasting my old templates into .blade.php files, and including whatever thing is needed to route it through the @layouts or controller.php (as implied in the forums ) and if so what needs to be left in tact, or can I literally delete the blade templates, and copy over my old ones into resources/views? Would I still need the app.blade.php file or can I delete that one too? Where do I put all my base-custom.php files in the new hierarchy? What do I do about the wrapper - will blade’s template inheritence work in its place or do I need to import my sage 8 wrapper, and if so to where?

So yeah, the announcement says you can use PHP instead of blade, but nowhere in the docs does it say ‘how’.

Blockquote PS: Did you try replacing wiredep with npm-wiredep before opting to strip it out entirely?

No have not tested that.

FontAwesome 5 Pro

Would it not be possible to use npm just for this specific dependency, even without migrating the other bower dependencies as long as they are working?

Thank you, these are great questions and I’ll update the [almost non-existent] Blade docs with some more details this week

1 Like

In this one example, yes, although my poor gulp skills would mean I’d be worried about how they’re handled by the gulpfile . I could even manually download and update it as part of assets/vendors. Regardless, it was just an example of the need to update dependencies that shouldn’t warrant a full theme redevelopment, and we rely on more than a few dependencies that have already or are planning to drop their public git/private bower repo in lieu of private npm repos.
Gonna give your suggestions a shot, and try out npm-wiredep and report back.

@ben - thanks! Looking forward :smile:

Hi @KimH, I am migrating to npm, but there’s one step that I don’t understand.
After replacing bower.json dependencies to package.json dependencies, how this dependencies are added to dist/main.js. Also with dist/main.css, it doesn’t add dependencies.

For example, libraries like owl.carousel.