DEV Community

Tomasz Wegrzanowski
Tomasz Wegrzanowski

Posted on

Upgrading old Imba 1 apps to run on modern Node

Node has the least stable ecosystem of all the commonly used languages. With Ruby or Python or frontend JavaScript, you can use take a project that's a few years old, and it will generally run just fine. Frontend JavaScript is one of the most stable languages.

With Node, it never happens. Every new Node version breaks pretty much every old package, and all you'll see is a wall of node-gyp errors.

This happened to me as well. Back when I was playing with various frameworks, I discovered Imba 1, and liked it quite a bit. So I built a lot of small apps, with Imba and SCSS. And of course SCSS won't work on latest Node. There was also a hell of webpack plugin dependencies involved, as Imba 1 and SCSS needed some webpack plugins, and I can't just upgrade that to latest version either.

GitHub's dependabot also keeps bothering me to upgrade dependencies to fix "security issues". This sounds like a good idea, except it has about >99% false positive rate overall, but the upgrades will absolutely break your apps.

While I was at it, I also did a Cypress upgrade, but that's an easy process of running cypress open and using builtin migration tool.

Dependencies

Before:

  "scripts": {
    "dev": "webpack-dev-server --mode=development --content-base dist/",
    "build": "webpack --mode=production",
    "watch": "webpack --watch --progress --colors --display-modules",
    "predeploy": "pnpm run build",
    "deploy": "gh-pages -d dist"
  },
  "dependencies": {
    "css-loader": "^1.0.1",
    "cypress": "^3.4.1",
    "express": "^4.16.2",
    "extract-text-webpack-plugin": "^4.0.0-beta.0",
    "gh-pages": "^2.0.1",
    "imba": "1.5.2",
    "normalize-scss": "^7.0.1",
    "style-loader": "^0.23.1",
    "webpack-dev-server": "^3.7.1"
    "node-sass": "^4.12.0",
    "sass-loader": "^7.1.0",
    "webpack": "^4.26.0",
    "webpack-cli": "^3.1.2"
  }
Enter fullscreen mode Exit fullscreen mode

After:

  "scripts": {
    "dev": "webpack-dev-server --mode=development --static dist/",
    "build": "webpack --mode=production",
    "watch": "webpack --watch --progress --colors --display-modules",
    "predeploy": "npm run build",
    "deploy": "gh-pages -d dist"
  },
  "dependencies": {
    "css-loader": "^5.2.7",
    "cypress": "^12.1.0",
    "gh-pages": "^4.0.0",
    "imba": "1.5.2",
    "mini-css-extract-plugin": "^1.6.2",
    "node-sass": "^8.0.0",
    "normalize-scss": "^7.0.1",
    "sass-loader": "^10.4.1",
    "webpack": "^4.46.0",
    "webpack-cli": "^4.10.0",
    "webpack-dev-server": "^4.11.1"
  }
Enter fullscreen mode Exit fullscreen mode

It took some serious trial and error. The important thing is that I needed to stay on Webpack 4 for Imba 1 to work, so for everything I picked the most recent version that still worked with Webpack 4. I fully expect it to stop working eventually, when Node 30 breaks Webpack 4, and all that code becomes unrunnable, while people can still run frontend JavaScript from the 90s without any issues whatsoever. But at least it fixes it for now.

webpack.config.js

Before:

let ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
  module: {
    rules: [
      {
        test: /\.imba$/,
        loader: 'imba/loader',
      },
      {
        test: /\.scss$/,
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: ['css-loader', 'sass-loader']
        })
      }
    ],
  },
  resolve: {
    extensions: [".imba", ".js", ".json", ".scss"]
  },
  entry: ["./src/app.imba", "./src/app.scss"],
  output: {  path: __dirname + '/dist', filename: "app.js" },
  plugins: [
    new ExtractTextPlugin('app.css')
  ]
}
Enter fullscreen mode Exit fullscreen mode

After:

let MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  module: {
    rules: [
      {
        test: /\.imba$/,
        loader: 'imba/loader',
      },
      {
        test: /\.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          "css-loader",
          "sass-loader",
        ]
      }
    ],
  },
  resolve: {
    extensions: [".imba", ".js", ".json", ".scss"]
  },
  entry: ["./src/app.imba", "./src/app.scss"],
  output: {  path: __dirname + '/dist', filename: "app.js" },
  plugins: [
    new MiniCssExtractPlugin({filename: 'app.css'})
  ]
}
Enter fullscreen mode Exit fullscreen mode

The plugin package changed, and so did its options.

Code

For now I upgraded imba-rotn package. The code is available here. It's also available online here.

Now I have about 30 more Imba 1 packages that all need similar fix.

Oldest comments (0)