Εισαγωγή στη Θεωρία Μηχανικής Μάθησης και τις Εφαρμογές της: Ένα οπτικό μάθημα με παραδείγματα
Επιστήμη Δεδομένων Και Βάσεις Δεδομένων
Η έννοια της διαμόρφωσης είναι εγγενές μέρος των περισσότερων σύγχρονων γλωσσών προγραμματισμού. Το JavaScript, ωστόσο, δεν διέθετε καμία επίσημη προσέγγιση στη διαμόρφωση μέχρι την άφιξη της τελευταίας έκδοσης του ECMAScript ES6.
Στο Node.js, ένα από τα πιο δημοφιλή πλαίσια JavaScript σήμερα, οι δέσμες λειτουργικών μονάδων επιτρέπουν τη φόρτωση Ενότητες NPM σε προγράμματα περιήγησης ιστού και βιβλιοθήκες προσανατολισμένες σε στοιχεία (όπως το React) ενθαρρύνουν και διευκολύνουν τη διαμόρφωση του κώδικα JavaScript.
Webpack είναι ένα από τα διαθέσιμα πακέτα λειτουργικών μονάδων που επεξεργάζεται JavaScript κώδικα, καθώς και όλα τα στατικά στοιχεία, όπως φύλλα στυλ, εικόνες και γραμματοσειρές, σε ένα ομαδοποιημένο αρχείο. Η επεξεργασία μπορεί να περιλαμβάνει όλες τις απαραίτητες εργασίες για τη διαχείριση και τη βελτιστοποίηση των εξαρτήσεων κώδικα, όπως συλλογή, συνένωση, ελαχιστοποίηση και συμπίεση.
Ωστόσο, η διαμόρφωση του Webpack και των εξαρτήσεων του μπορεί να είναι αγχωτική και δεν είναι πάντα μια απλή διαδικασία, ειδικά για αρχάριους.
πώς να αποκτήσετε τον πρώτο σας πελάτη συμβούλων
Αυτή η ανάρτηση ιστολογίου παρέχει οδηγίες, με παραδείγματα, σχετικά με τον τρόπο διαμόρφωσης του Webpack για διαφορετικά σενάρια και επισημαίνει τις πιο συνηθισμένες παγίδες που σχετίζονται με τη δέσμευση εξαρτήσεων έργου χρησιμοποιώντας το Webpack.
Το πρώτο μέρος αυτής της ανάρτησης ιστολογίου εξηγεί πώς να απλοποιήσετε τον ορισμό των εξαρτήσεων σε ένα έργο. Στη συνέχεια, συζητάμε και επιδεικνύουμε διαμόρφωση για τον διαχωρισμό κώδικα πολλαπλών και μονών σελίδων εφαρμογών. Τέλος, συζητάμε πώς να διαμορφώσουμε το Webpack, εάν θέλουμε να συμπεριλάβουμε βιβλιοθήκες τρίτων στο έργο μας.
Οι σχετικές διαδρομές δεν σχετίζονται άμεσα με εξαρτήσεις, αλλά τις χρησιμοποιούμε όταν ορίζουμε εξαρτήσεις. Εάν μια δομή αρχείου έργου είναι περίπλοκη, μπορεί να είναι δύσκολο να επιλυθούν σχετικές διαδρομές λειτουργικής μονάδας. Ένα από τα πιο θεμελιώδη οφέλη της διαμόρφωσης Webpack είναι ότι βοηθά στην απλοποίηση του ορισμού των σχετικών διαδρομών σε ένα έργο.
Ας υποθέσουμε ότι έχουμε την ακόλουθη δομή έργου:
- Project - node_modules - bower_modules - src - script - components - Modal.js - Navigation.js - containers - Home.js - Admin.js
Μπορούμε να αναφέρουμε εξαρτήσεις με σχετικές διαδρομές στα αρχεία που χρειαζόμαστε και αν θέλουμε να εισαγάγουμε στοιχεία σε κοντέινερ στον πηγαίο κώδικα, μοιάζει με το εξής:
Home.js
Import Modal from ‘../components/Modal’; Import Navigation from ‘../components/Navigation’;
Modal.js
import {datepicker} from '../../../../bower_modules/datepicker/dist/js/datepicker';
Κάθε φορά που θέλουμε να εισαγάγουμε ένα σενάριο ή μια ενότητα, πρέπει να γνωρίζουμε τη θέση του τρέχοντος καταλόγου και να βρούμε τη σχετική διαδρομή προς αυτό που θέλουμε να εισαγάγουμε. Μπορούμε να φανταστούμε πώς αυτό το ζήτημα μπορεί να κλιμακωθεί σε πολυπλοκότητα εάν έχουμε ένα μεγάλο έργο με ένθετη δομή αρχείων ή θέλουμε να αναδιαμορφώσουμε ορισμένα μέρη μιας σύνθετης δομής έργου.
Μπορούμε να χειριστούμε εύκολα αυτό το ζήτημα με το Webpack's resolve.alias
επιλογή. Μπορούμε να δηλώσουμε τα λεγόμενα ψευδώνυμα - όνομα καταλόγου ή λειτουργικής μονάδας με την τοποθεσία του και δεν βασίζουμε σε σχετικές διαδρομές στον πηγαίο κώδικα του έργου.
webpack.config.js
resolve: { alias: { 'node_modules': path.join(__dirname, 'node_modules'), 'bower_modules': path.join(__dirname, 'bower_modules'), } }
Στο Modal.js
αρχείο, μπορούμε τώρα να εισάγουμε το πρόγραμμα επιλογής δεδομένων πολύ πιο απλό:
import {datepicker} from 'bower_modules/datepicker/dist/js/datepicker';
Μπορούμε να έχουμε σενάρια όπου πρέπει να προσθέσουμε ένα σενάριο στο τελικό πακέτο, ή να χωρίσουμε το τελικό πακέτο, ή θέλουμε να φορτώσουμε ξεχωριστά πακέτα κατά παραγγελία. Η ρύθμιση της διαμόρφωσης έργου και Webpack για αυτά τα σενάρια ενδέχεται να μην είναι απλή.
Στη διαμόρφωση του Webpack, το Entry
Η επιλογή λέει στο Webpack πού είναι το σημείο εκκίνησης για το τελικό πακέτο. Ένα σημείο εισόδου μπορεί να έχει τρεις διαφορετικούς τύπους δεδομένων: String, Array ή Object.
Εάν έχουμε ένα μόνο σημείο εκκίνησης, μπορούμε να χρησιμοποιήσουμε οποιαδήποτε από αυτές τις μορφές και να έχουμε το ίδιο αποτέλεσμα.
Εάν θέλουμε να προσθέσουμε πολλά αρχεία και δεν εξαρτώνται το ένα από το άλλο, μπορούμε να χρησιμοποιήσουμε μια μορφή Array. Για παράδειγμα, μπορούμε να προσαρτήσουμε analytics.js
στο τέλος του bundle.js
:
webpack.config.js
module.exports = { // creates a bundle out of index.js and then append analytics.js entry: ['./src/script/index.jsx', './src/script/analytics.js'], output: { path: './build', filename: bundle.js ' } };
Ας υποθέσουμε ότι έχουμε μια εφαρμογή πολλών σελίδων με πολλά αρχεία HTML, όπως index.html
και admin.html
. Μπορούμε να δημιουργήσουμε πολλαπλές δέσμες χρησιμοποιώντας το σημείο εισόδου ως τύπο αντικειμένου. Η παρακάτω διαμόρφωση δημιουργεί δύο δέσμες JavaScript:
webpack.config.js
module.exports = { entry: { index: './src/script/index.jsx', admin: './src/script/admin.jsx' }, output: { path: './build', filename: '[name].js' // template based on keys in entry above (index.js & admin.js) } };
index.html
admin.html
CommonsChunkPlugin
webpack.config.js
Και οι δύο δέσμες JavaScript μπορούν να μοιράζονται κοινές βιβλιοθήκες και στοιχεία. Για αυτό, μπορούμε να χρησιμοποιήσουμε το var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('common.js'); module.exports = { entry: { index: './src/script/index.jsx', admin: './src/script/admin.jsx' }, output: { path: './build', filename: '[name].js' // template based on keys in entry above (index.js & admin.js) }, plugins: [commonsPlugin] };
, το οποίο βρίσκει λειτουργικές μονάδες που εμφανίζονται σε πολλά κομμάτια εισόδου και δημιουργεί ένα κοινό πακέτο που μπορεί να αποθηκευτεί προσωρινά σε πολλές σελίδες.
require.ensure
System.import
Τώρα, δεν πρέπει να ξεχνάμε να προσθέτουμε πριν από δέσμες σεναρίων.
Το Webpack μπορεί να χωρίσει στατικά στοιχεία σε μικρότερα κομμάτια και αυτή η προσέγγιση είναι πιο ευέλικτη από την τυπική συνένωση. Εάν έχουμε μια μεγάλη εφαρμογή μιας σελίδας (SPA), η απλή συνένωση σε ένα πακέτο δεν είναι καλή προσέγγιση, επειδή η φόρτωση ενός τεράστιου πακέτου μπορεί να είναι αργή και οι χρήστες συνήθως δεν χρειάζονται όλες τις εξαρτήσεις σε κάθε προβολή.
τι μπορώ να κάνω με το node js
Εξηγήσαμε νωρίτερα πώς να χωρίσουμε μια εφαρμογή σε πολλά πακέτα, να συνενώσουμε κοινές εξαρτήσεις και να επωφεληθούμε από τη συμπεριφορά προσωρινής αποθήκευσης του προγράμματος περιήγησης. Αυτή η προσέγγιση λειτουργεί πολύ καλά για εφαρμογές πολλαπλών σελίδων, αλλά όχι για εφαρμογές μιας σελίδας.
Για το SPA, θα πρέπει να παρέχουμε μόνο τα στατικά στοιχεία που απαιτούνται για την απόδοση της τρέχουσας προβολής. Ο δρομολογητής από την πλευρά του πελάτη στην αρχιτεκτονική SPA είναι το ιδανικό μέρος για τη διαχείριση του διαχωρισμού κώδικα. Όταν ο χρήστης μπαίνει σε μια διαδρομή, μπορούμε να φορτώσουμε μόνο τις απαραίτητες εξαρτήσεις για την προκύπτουσα προβολή. Εναλλακτικά, μπορούμε να φορτώσουμε εξαρτήσεις καθώς ο χρήστης κάνει κύλιση σε μια σελίδα.
Για το σκοπό αυτό, μπορούμε να χρησιμοποιήσουμε admin.jsx
ή import React, {Component} from 'react'; export default class Admin extends Component { render() { return Admin ; } }
λειτουργίες, τις οποίες το Webpack μπορεί να ανιχνεύσει στατικά. Το Webpack μπορεί να δημιουργήσει ένα ξεχωριστό πακέτο με βάση αυτό το διαχωριστικό σημείο και να το καλέσει κατ 'απαίτηση.
Σε αυτό το παράδειγμα, έχουμε δύο δοχεία React. προβολή διαχειριστή και προβολή πίνακα ελέγχου.
dashboard.jsx
import React, {Component} from 'react'; export default class Dashboard extends Component { render() { return Dashboard ; } }
/dashboard
/admin
Εάν ο χρήστης εισέλθει είτε στο index.jsx
ή if (window.location.pathname === '/dashboard') { require.ensure([], function() { require('./containers/dashboard').default; }); } else if (window.location.pathname === '/admin') { require.ensure([], function() { require('./containers/admin').default; }); }
URL, φορτώνεται μόνο το αντίστοιχο απαιτούμενο πακέτο JavaScript. Παρακάτω μπορούμε να δούμε παραδείγματα με και χωρίς το δρομολογητή από την πλευρά του πελάτη.
index.jsx
ReactDOM.render( {props.children} }> { require.ensure([], function (require) { cb(null, require('./containers/dashboard').default) }, 'dashboard')}} /> { require.ensure([], function (require) { cb(null, require('./containers/admin').default) }, 'admin')}} /> , document.getElementById('content') );
style-loader
css-loader
Στο Webpack, φορτωτές , όπως ExtractTextWebpackPlugin
και webpack.config.js
, προεπεξεργαστείτε τα φύλλα στυλ και ενσωματώστε τα στο πακέτο JavaScript εξόδου, αλλά σε ορισμένες περιπτώσεις, μπορούν να προκαλέσουν Λάμψη ασταθούς περιεχομένου (ΦΟΥΚ) .
Μπορούμε να αποφύγουμε το FOUC με var ExtractTextPlugin = require('extract-text-webpack-plugin'); module.exports = { module: { loaders: [{ test: /.css/, loader: ExtractTextPlugin.extract('style', 'css’)' }], }, plugins: [ // output extracted CSS to a file new ExtractTextPlugin('[name].[chunkhash].css') ] }
που επιτρέπει τη δημιουργία όλων των στυλ σε ξεχωριστά πακέτα CSS αντί να ενσωματωθούν στην τελική δέσμη JavaScript.
$
jQuery
Πολλές φορές, πρέπει να χρησιμοποιούμε βιβλιοθήκες τρίτων, διάφορες προσθήκες ή πρόσθετα σενάρια, επειδή δεν θέλουμε να ξοδεύουμε χρόνο για την ανάπτυξη των ίδιων στοιχείων από το μηδέν. Υπάρχουν πολλές διαθέσιμες βιβλιοθήκες και προσθήκες παλαιού τύπου που δεν συντηρούνται ενεργά, δεν καταλαβαίνουν τις λειτουργικές μονάδες JavaScript και υποθέτουν την παρουσία εξαρτήσεων παγκοσμίως με προκαθορισμένα ονόματα.
Ακολουθούν ορισμένα παραδείγματα με τα πρόσθετα jQuery, με μια εξήγηση για το πώς να ρυθμίσετε σωστά το Webpack για να δημιουργήσετε το τελικό πακέτο.
Τα περισσότερα πρόσθετα τρίτων εξαρτώνται από την παρουσία συγκεκριμένων καθολικών εξαρτήσεων. Στην περίπτωση του jQuery, τα πρόσθετα βασίζονται στο $(‘div.content’).pluginFunc()
ή ProvidePlugin
η μεταβλητή καθορίζεται και μπορούμε να χρησιμοποιήσουμε τα πρόσθετα jQuery καλώντας var $ = require('jquery')
στον κωδικό μας.
Μπορούμε να χρησιμοποιήσουμε την προσθήκη Webpack $
για προσθήκη webpack.config.js
κάθε φορά που συναντά το παγκόσμιο webpack.ProvidePlugin({ ‘$’: ‘jquery’, })
αναγνωριστικό.
$
require
Όταν το Webpack επεξεργάζεται τον κωδικό, αναζητά την παρουσία $
και παρέχει μια αναφορά σε καθολικές εξαρτήσεις χωρίς να εισάγει τη λειτουργική μονάδα που καθορίζεται από το this
λειτουργία.
Ορισμένες προσθήκες jQuery υποθέτουν window
στον παγκόσμιο χώρο ονομάτων ή βασιστείτε στο imports-loader
είναι το example.js
αντικείμενο. Για το σκοπό αυτό, μπορούμε να χρησιμοποιήσουμε $(‘div.content’).pluginFunc();
που εισάγει καθολικές μεταβλητές σε ενότητες.
πώς να υπολογίσετε την τιμή επιλογής
$
imports-loader
Στη συνέχεια, μπορούμε να εγχύσουμε το require('imports?$=jquery!./example.js');
μεταβλητή στη λειτουργική μονάδα διαμορφώνοντας το var $ = require('jquery');
:
example.js
Αυτό προετοιμάζει απλώς webpack.config.js
έως module: { loaders: [{ test: /jquery-plugin/, loader: 'imports?jQuery=jquery,$=jquery,this=>window' }] }
.
Στη δεύτερη περίπτωση χρήσης:
=>
this
Χρησιμοποιώντας το window
σύμβολο (να μην συγχέεται με το Λειτουργίες βέλους ES6 ), μπορούμε να ορίσουμε αυθαίρετες μεταβλητές. Η τελευταία τιμή επαναπροσδιορίζει την καθολική μεταβλητή (function () { ... }).call(window);
για να δείξετε το this
αντικείμενο. Είναι το ίδιο με το περιτύλιγμα ολόκληρου του περιεχομένου του αρχείου με το window
και κλήση // CommonJS var $ = require('jquery'); // jquery is available // AMD define([‘jquery’], function($) { // jquery is available });
λειτουργία με jquery-plugin.js
ως επιχείρημα.
Μπορούμε επίσης να απαιτήσουμε βιβλιοθήκες χρησιμοποιώντας τη μορφή λειτουργικής μονάδας CommonJS ή AMD:
(function(factory) { if (typeof define === 'function' && define.amd) { // AMD format is used define(['jquery'], factory); } else if (typeof exports === 'object') { // CommonJS format is used module.exports = factory(require('jquery')); } else { // Neither AMD nor CommonJS used. Use global variables. } });
Ορισμένες βιβλιοθήκες και λειτουργικές μονάδες μπορούν να υποστηρίξουν διαφορετικές μορφές λειτουργικών μονάδων.
Στο επόμενο παράδειγμα, έχουμε μια προσθήκη jQuery που χρησιμοποιεί τη μορφή μονάδας AMD και CommonJS και έχει μια εξάρτηση jQuery:
webpack.config.js
module: { loaders: [{ test: /jquery-plugin/, loader: 'imports?define=>false,exports=>false' }] }
define
μετατροπή εργολάβου σε μισθό πλήρους απασχόλησης
false
Μπορούμε να επιλέξουμε ποια μορφή ενότητας θέλουμε να χρησιμοποιήσουμε για τη συγκεκριμένη βιβλιοθήκη. Εάν δηλώσουμε exports
να ισούται με false
, το Webpack δεν αναλύει τη λειτουργική μονάδα σε μορφή μονάδας AMD και αν δηλώσουμε τη μεταβλητή expose-loader
να ισούται με webpack.config.js
, το Webpack δεν αναλύει τη λειτουργική μονάδα σε μορφή λειτουργικής μονάδας CommonJS.
Εάν χρειαστεί να εκθέσουμε μια ενότητα στο παγκόσμιο πλαίσιο, μπορούμε να χρησιμοποιήσουμε module: { loaders: [ test: require.resolve('jquery'), loader: 'expose-loader?jQuery!expose-loader?$' ] }
. Αυτό μπορεί να είναι χρήσιμο, για παράδειγμα, εάν έχουμε εξωτερικά σενάρια που δεν αποτελούν μέρος της διαμόρφωσης Webpack και βασίζουμε το σύμβολο στον παγκόσμιο χώρο ονομάτων ή χρησιμοποιούμε προσθήκες προγράμματος περιήγησης που πρέπει να έχουν πρόσβαση σε ένα σύμβολο στην κονσόλα του προγράμματος περιήγησης.
window.$ window.jQuery
externals
Η βιβλιοθήκη jQuery είναι πλέον διαθέσιμη στον παγκόσμιο χώρο ονομάτων για άλλα σενάρια στην ιστοσελίδα.
webpack.config.js
Εάν θέλουμε να συμπεριλάβουμε ενότητες από εξωτερικά φιλοξενούμενα σενάρια, πρέπει να τα ορίσουμε στη διαμόρφωση. Διαφορετικά, το Webpack δεν μπορεί να δημιουργήσει το τελικό πακέτο.
Μπορούμε να διαμορφώσουμε εξωτερικά σενάρια χρησιμοποιώντας το externals: { react: 'React', 'react-dom': 'ReactDOM' }
επιλογή στη διαμόρφωση Webpack. Για παράδειγμα, μπορούμε να χρησιμοποιήσουμε μια βιβλιοθήκη από ένα CDN μέσω μιας χωριστής ετικέτας, ενώ εξακολουθούμε να το δηλώνουμε ρητά ως εξάρτηση λειτουργικής μονάδας στο έργο μας.
project | |-- node_modules | |-- react |-- react-plugin | |--node_modules | |--react
react-plugin
Είναι υπέροχο να χρησιμοποιείτε τον διαχειριστή πακέτων NPM στην ανάπτυξη διεπαφής για τη διαχείριση βιβλιοθηκών και εξαρτήσεων τρίτων. Ωστόσο, μερικές φορές μπορούμε να έχουμε πολλές παρουσίες της ίδιας βιβλιοθήκης με διαφορετικές εκδόσεις και δεν παίζουν μαζί καλά σε ένα περιβάλλον.
Αυτό θα μπορούσε να συμβεί, για παράδειγμα, με τη βιβλιοθήκη React, όπου μπορούμε να εγκαταστήσουμε το React από το NPM και αργότερα μια διαφορετική έκδοση του React μπορεί να είναι διαθέσιμη με κάποιο πρόσθετο πακέτο ή προσθήκη. Η δομή του έργου μας μπορεί να έχει την εξής μορφή:
webpack.config.js
Εξαρτήματα που προέρχονται από το module.exports = { resolve: { alias: { 'react': path.join(__dirname, './node_modules/react'), 'react/addons': path.join(__dirname, '/node_modules/react/addons'), } } }
έχουν διαφορετική παρουσία React από τα υπόλοιπα στοιχεία του έργου. Τώρα έχουμε δύο ξεχωριστά αντίγραφα του React, και μπορεί να είναι διαφορετικές εκδόσεις. Στην εφαρμογή μας, αυτό το σενάριο μπορεί να βλάψει το παγκόσμιο μεταβλητό DOM και μπορούμε να δούμε μηνύματα σφάλματος στο αρχείο καταγραφής της κονσόλας ιστού. Η λύση σε αυτό το πρόβλημα είναι να έχουμε την ίδια έκδοση του React σε ολόκληρο το έργο. Μπορούμε να το λύσουμε με ψευδώνυμα Webpack.
react-plugin
node_modules
Πότε console.log(React.version)
προσπαθεί να απαιτήσει το React, χρησιμοποιεί την έκδοση στο έργο του
|_+_|. Αν θέλουμε να μάθουμε ποια έκδοση του React χρησιμοποιούμε, μπορούμε να προσθέσουμε
|_+_|στον πηγαίο κώδικα.
Αυτή η ανάρτηση απλώς χαράζει την επιφάνεια της δύναμης και της χρησιμότητας του Webpack.
Υπάρχουν πολλά άλλα Webpack φορτωτές και προσθήκες που θα σας βοηθήσουν να βελτιστοποιήσετε και να βελτιώσετε τη δέσμευση JavaScript.
Ακόμα κι αν είστε αρχάριος, αυτός ο οδηγός σάς προσφέρει ένα σταθερό έδαφος για να ξεκινήσετε να χρησιμοποιείτε το Webpack, το οποίο θα σας επιτρέψει να εστιάσετε περισσότερο στην ανάπτυξη λιγότερο στη διαμόρφωση πακέτων.
Σχετίζεται με: Maintain Control: Ένας οδηγός για το Webpack and React, Pt. 1