Michael HönnigMichael Hönnig

You know these ugly ES6/TypeScript import statements with endless sequences of "../../.." like in this example:


import { Topic} from '../../../services/domain/topic';
import { Rating } from '../../../services/domain/rating';
import { SmartAudio } from '../../../providers/smart-audio/smart-audio';
import { ENGLISH_GERMAN_DEFAULTS } from '../../../data/english-german';
[...]

And even worse, once you move your code to another directory, the number of ".." in these relative paths does not match the target anymore? I wanted to get rid of these in my current project, looked for a solution and found some good hints on the web: [1], [2] and [3]. Thanks to you guys! In this article I'd like to show how I applied these to my TypesScript 2.4 / Angular 5 / Ionic 3 project:

webpack.config.ts

Ionic v3 brings it's own webpack.config.js in node_modules/@ionic/app-scripts/config/. So, you cannot just create your own, but you have to patch the existing one. So I copied this file to my project root (you could also create a subdirectory for such configurations), and amended as show here - see [HERE] tags:


function getProdLoaders() {
   [...]
}

// [HERE] a helper function for alias definitions
function asPath(srcSubDir) {
  return path.join(__dirname, "src", srcSubDir);
}

var devConfig = {
  [...]
  resolve: {
    extensions: ['.ts', '.js', '.json'],
    // [HERE] ./src is for getting rid of endless ../../.. in imports
    // see also tsconfig.json
    modules: [path.resolve('./src'), path.resolve('node_modules')],

    // [HERE] some aliases for imports,
    // tsconfig.json also needs to be maintained
    alias: {
      "$data": asPath('services')
    }
  },
[...]

And the same for prodConfig = !

To be able to easily re-apply these changes once Ionic changed their webpack.config.js, you can create a diff file using this command (Linux):


diff -Naur node_modules/@ionic/app-scripts/config/webpack.config.js \
   webpack.config.js >webpack.config.js-patch

And re-apply it with:


cp node_modules/@ionic/app-scripts/config/webpack.config.js webpack.config.js
patch <webpack.config.js-patch

package.json

To make the Ionic build system use your patched webpack.config.js, you need to amend your package.json file as follows:


"config": {
     "ionic_source_map": "source-map",
     "ionic_copy": "./config/copy.config.js",
     "ionic_sass": "./config/sass.config.js",
     // [HERE] make Ionic use our patched webpack.config.js
     "ionic_bundler": "webpack",
     "ionic_webpack": "webpack.config.js"
   },

tsconfig.json

For TypeScript source code you also need to defines these in your tsconfig.json file:


"compilerOptions": {
    [...]
    // getting rid of endless ../../... in imports
    "baseUrl": "src",

    // and some neat aliases for imports
    "paths": {
      // webpack.config.js also needs to be maintained
      "~data/*": [ "services/*" ]
    }
   },

the result

Now you can write these imports as follows:


import { Topic} from 'services/domain/topic';
import { Rating } from 'services/domain/rating';
import { SmartAudio } from 'providers/smart-audio/smart-audio';
import { ENGLISH_GERMAN_DEFAULTS } from '$data/english-german';
[...]

As you can see, there are actually two unrelated changes:

  1. automatically resolve '.src' for absolute imports
  2. definition of an alias '$data', where the '$' is just to avoid name conflicts - you can define as many aliases as you like

Comments welcome on Twitter

You are welcome to contact me Me on Twitter or send your reply to this article via Twitter.


References:

[1] https://decembersoft.com/posts/say-goodbye-to-relative-paths-in-typescript-imports/ [2] https://stackoverflow.com/questions/41512923/how-to-extend-default-webpack-config-in-ionic-v2 [3] https://stackoverflow.com/questions/43107233/configuration-resolve-has-an-unknown-property-root