Skip to content

Instantly share code, notes, and snippets.

@leonardfactory
Last active July 11, 2016 20:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leonardfactory/f5ba0dc9874d01f22b74 to your computer and use it in GitHub Desktop.
Save leonardfactory/f5ba0dc9874d01f22b74 to your computer and use it in GitHub Desktop.
Un insieme di note per la configurazione di un ambiente di sviluppo per ES6, sia frontend che backend.

ES6 Dev Notes

Un insieme di note per la configurazione di un ambiente di sviluppo per ES6, sia frontend che backend. Perché per quanto Webpack sia un labirinto, con un filo di arianna la strada si può trovare.

Webpack

Configurazione in ES6 (con Babel)

Per utilizzare ES6 nel config di Webpack è necessario:

  • Chiamare il file webpack.config.babel.js (per far riconoscere a webpack che è necessario chiamare il babel-loader).

  • Installare babel-loader (npm i --save-dev babel-core babel-loader)

  • Installare i plugin e i preset necessari, ad esempio:

    "devDependencies": {
      "babel-plugin-transform-flow-strip-types": "^6.7.0",
      "babel-preset-es2015": "^6.6.0",
      "babel-preset-react": "^6.5.0",
      "babel-preset-stage-0": "^6.5.0"
    }
  • Creare un file .babelrc per far riconoscere a webpack quali opzioni utilizzare per il webpack.config.babel.js

    {
      "presets": ["react", "es2015", "stage-0"],
      "plugins": [
        "transform-flow-strip-types"
      ]
    }

Entry

Le entry sono sempre percorsi 'relativi'. Utilizzare ad esempio ./index.js al posto di index.js.

export default {
  entry: './index.js'
  // ..
}

Output

  • Target di default è web (Front-End), mentre invece per il Back-end bisogna specificare node
  • output.libraryTarget specificare 'commonjs2' in caso il codice debba essere utilizzato da node.
export default {
  // ..
  target: 'node', // Di default è 'web' ed è ok per il front-end
  output: {
    filename: 'server.js', // Oppure [name].js in caso di più entry
    path: distPath, // Path Assoluta
    publicPath: publicPath, // Path relativa i.e. `dist/`
    libraryTarget: 'commonjs2' // Necessario in caso il codice sia per un server, quindi Node.
  }
}

Externals

Gli external permettono di far ignorare a WebPack degli import specifici, in modo tale che vengano presi dall'Environment e non debbano essere cercati all'interno dei file dell'applicazione.

E' necessario specialmente lato backend, per evitare che vengano compressi all'interno del Bundle finale le dipendenze, che invece rimangono gestite dal sistema di import di Node.js.

// Più semplice, ma in realtà meno corretto:
externals: /^[a-z\-0-9]+$/,
...

// Più preciso ma lungo
let nodeModules = fs.readdirSync('node_modules')
  .filter((x) => ['.bin'].indexOf(x) === -1 });
  
export default {
  ...  
  externals: (context, request, callback) => {
    var pathStart = request.split('/')[0];
    if(nodeModules.indexOf(pathStart) >= 0 && request != 'webpack/hot/signal.js') {
      return callback(null, "commonjs " + request);
    };
    callback();
  }
}

Source Map

Lato Server

Per supportare le SourceMap, è necessario utilizzare (lato server) la libreria source-map-support (su npm). Quindi eseguire npm i source-map-support --save-dev, e poi aggiungere nel config di Webpack:

export default {
  ...
  devtool: 'source-map',
  plugins: [
    new webpack.BannerPlugin('require("source-map-support").install();',
                          { raw: true, entryOnly: false }),
    ...
  ]
}

ES6

Arrow functions (Lambda)

Le lambda, o arrow function permettono di utilizzare una sintassi più semplice per la definizione di funzioni:

let fun = (param, other) => {
  ...
}

In caso di un solo parametro, le parentesi possono essere omesse:

let squared = n => {
  return n * n
}

Inoltre, in caso il corpo della funzione sia composto da un solo statement, è possibile omettere le parentesi graffe e l'istruzione di return.

let squared = n => n * n

Lexical this

Caratteristica fondamentale delle Lambda è quella di catturare il this del contesto in cui vengono definite, senza definirne uno nuovo come accade per le function(){}, ad esempio:

let heroDisplay = {
  name: 'Luke Skywalker',
  displayLater: function() {
    /**
     * Senza il `lexical this`, `this.name` sarebbe stato 'undefined'
     */
    setTimeout(() => console.log('Il mio eroe è ' + this.name));
  }
}

heroDisplay.displayLater(); // stampa 'Il mio eroe è Luke Skywalker'

Classi

// Definizione classe
class Hero {
  // Costruttore chiamato con la keyword new
  constructor(name) {
    this.name = name;
  }
  
  // Metodo definito senza utilizzare la keyword `function`
  displayName() {
    console.log(this.name);
  }
}

let hero = new Hero('Michael Jordan');
hero.displayName();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment