Webpack 入門指南 - 1.安裝
Webpack 是目前流行的打包工具,如何安裝它呢?
1. 安裝 Node Js
首先,Webpack 是基于 NodeJs 的工具,你必須首先安裝 NodeJs. NodeJs 僅僅只需要在你的系統(tǒng)中安裝一次就可以了。
2. 全局安裝 Webpack
我們希望能夠在系統(tǒng)的任何文件夾中使用 Webpack,使用的方式是通過 Webpack 命令來完成的,這需要我們?nèi)职惭b Webpack。這也只需要安裝一次,以后每個項目就不需要重新全局安裝了。
$ npm install webpack -g
成功安裝之后,你應(yīng)該能夠在任何目錄中執(zhí)行 webpack 命令,如果你還沒有項目的配置文件的話,應(yīng)該會看到當(dāng)前的 Webpack 版本和一個命令的幫助列表。
> webpack webpack 1.12.12 Usage: https://webpack.github.io/docs/cli.html Options: --help, -h, -? --config --context --entry --module-bind --module-bind-post --module-bind-pre --output-path --output-file --output-chunk-file --output-named-chunk-file --output-source-map-file --output-public-path --output-jsonp-function --output-pathinfo --output-library --output-library-target --records-input-path --records-output-path --records-path --define --target --cache [default: true] --watch, -w --watch which closes when stdin ends --watch-aggregate-timeout --watch-poll --hot --debug --devtool --progress --resolve-alias --resolve-loader-alias --optimize-max-chunks --optimize-min-chunk-size --optimize-minimize --optimize-occurence-order --optimize-dedupe --prefetch --provide --labeled-modules --plugin --bail --profile -d shortcut for --debug --devtool sourcemap --output-pathinfo -p shortcut for --optimize-minimize --json, -j --colors, -c --sort-modules-by --sort-chunks-by --sort-assets-by --hide-modules --display-exclude --display-modules --display-chunks --display-error-details --display-origins --display-cached --display-cached-assets --display-reasons, --verbose, -v Output filename not configured. PS C:\study\webpack\w1>
注意,最后還提示你,當(dāng)前沒有找到 webpack 配置文件。
3. 在項目中安裝 Webpack
最好在你的項目中也包含一份獨立的 Webpack,這樣你更方便管理你的項目。為什么又是全局安裝,又是局部安裝呢?可以參考這里的說明。
3.1 確認(rèn)創(chuàng)建 NPM 項目文件
首先,你需要已經(jīng)創(chuàng)建了 NPM 的項目文件,如果沒有的話,使用 init 命令創(chuàng)建它。
npm init
你需要回答一系列問題。最終你會得到一個名為 package.json 的 NPM 項目文件,如果你愿意的話,手工創(chuàng)建它也不錯。甚至你可以直接復(fù)制一個過來。
一個新創(chuàng)建的 package.json 內(nèi)容應(yīng)該如下所示。
{ "name": "w1", "version": "1.0.0", "description": "", "main": "index.js", "dependencies": {}, "devDependencies": {}, "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC" }
3.2 在項目中安裝 Webpack
現(xiàn)在,可以在項目中安裝 Webpack 了,直接使用 NPM 的 install 命令。
npm install webpack --save-dev
--save-dev 的意思是說 webpack 是一個開發(fā)工具,我們需要將這一點保存到 package.Json 文件中。
install 命令可以簡化為單個字符 i,注意是小寫的 i。
--save-dev 還可以簡化為大寫的 S,寫成 -S,你可以在這里查看 instal 的更詳細(xì)使用說明。
npm i webpack --S
你應(yīng)該看到一個長長的輸出,這是由于 Webpack 是一個很復(fù)雜的工具。它依賴很多的其它工具。
> npm install webpack --save-dev w1@1.0.0 w1 `-- webpack@1.13.2 +-- acorn@3.3.0 +-- async@1.5.2 +-- clone@1.0.2 +-- enhanced-resolve@0.9.1 | +-- graceful-fs@4.1.9 | `-- memory-fs@0.2.0 +-- interpret@0.6.6 +-- loader-utils@0.2.16 | +-- big.js@3.1.3 | +-- emojis-list@2.1.0 | +-- json5@0.5.0 | `-- object-assign@4.1.0 +-- memory-fs@0.3.0 | +-- errno@0.1.4 | | `-- prr@0.0.0 | `-- readable-stream@2.1.5 | +-- buffer-shims@1.0.0 | +-- core-util-is@1.0.2 | +-- inherits@2.0.3 | +-- isarray@1.0.0 | +-- process-nextick-args@1.0.7 | `-- util-deprecate@1.0.2 +-- mkdirp@0.5.1 | `-- minimist@0.0.8 +-- node-libs-browser@0.6.0 | +-- assert@1.4.1 | +-- browserify-zlib@0.1.4 | | `-- pako@0.2.9 | +-- buffer@4.9.1 | | +-- base64-js@1.2.0 | | `-- ieee754@1.1.8 | +-- console-browserify@1.1.0 | | `-- date-now@0.1.4 | +-- constants-browserify@0.0.1 | +-- crypto-browserify@3.2.8 | | +-- pbkdf2-compat@2.0.1 | | +-- ripemd160@0.2.0 | | `-- sha.js@2.2.6 | +-- domain-browser@1.1.7 | +-- events@1.1.1 | +-- http-browserify@1.7.0 | | `-- Base64@0.2.1 | +-- https-browserify@0.0.0 | +-- os-browserify@0.1.2 | +-- path-browserify@0.0.0 | +-- process@0.11.9 | +-- punycode@1.4.1 | +-- querystring-es3@0.2.1 | +-- readable-stream@1.1.14 | | `-- isarray@0.0.1 | +-- stream-browserify@1.0.0 | | `-- readable-stream@1.1.14 | | `-- isarray@0.0.1 | +-- string_decoder@0.10.31 | +-- timers-browserify@1.4.2 | +-- tty-browserify@0.0.0 | +-- url@0.10.3 | | +-- punycode@1.3.2 | | `-- querystring@0.2.0 | +-- util@0.10.3 | | `-- inherits@2.0.1 | `-- vm-browserify@0.0.4 | `-- indexof@0.0.1 +-- optimist@0.6.1 | `-- wordwrap@0.0.3 +-- supports-color@3.1.2 | `-- has-flag@1.0.0 +-- tapable@0.1.10 +-- uglify-js@2.6.4 | +-- async@0.2.10 | +-- source-map@0.5.6 | +-- uglify-to-browserify@1.0.2 | `-- yargs@3.10.0 | +-- camelcase@1.2.1 | +-- cliui@2.1.0 | | +-- center-align@0.1.3 | | | +-- align-text@0.1.4 | | | | +-- longest@1.0.1 | | | | `-- repeat-string@1.5.4 | | | `-- lazy-cache@1.0.4 | | +-- right-align@0.1.3 | | `-- wordwrap@0.0.2 | +-- decamelize@1.2.0 | `-- window-size@0.1.0 +-- watchpack@0.2.9 | +-- async@0.9.2 | `-- chokidar@1.6.1 | +-- anymatch@1.3.0 | | +-- arrify@1.0.1 | | `-- micromatch@2.3.11 | | +-- arr-diff@2.0.0 | | | `-- arr-flatten@1.0.1 | | +-- array-unique@0.2.1 | | +-- braces@1.8.5 | | | +-- expand-range@1.8.2 | | | | `-- fill-range@2.2.3 | | | | +-- is-number@2.1.0 | | | | +-- isobject@2.1.0 | | | | `-- randomatic@1.1.5 | | | +-- preserve@0.2.0 | | | `-- repeat-element@1.1.2 | | +-- expand-brackets@0.1.5 | | | `-- is-posix-bracket@0.1.1 | | +-- extglob@0.3.2 | | +-- filename-regex@2.0.0 | | +-- kind-of@3.0.4 | | | `-- is-buffer@1.1.4 | | +-- normalize-path@2.0.1 | | +-- object.omit@2.0.0 | | | +-- for-own@0.1.4 | | | | `-- for-in@0.1.6 | | | `-- is-extendable@0.1.1 | | +-- parse-glob@3.0.4 | | | +-- glob-base@0.3.0 | | | `-- is-dotfile@1.0.2 | | `-- regex-cache@0.4.3 | | +-- is-equal-shallow@0.1.3 | | `-- is-primitive@2.0.0 | +-- async-each@1.0.1 | +-- glob-parent@2.0.0 | +-- is-binary-path@1.0.1 | | `-- binary-extensions@1.7.0 | +-- is-glob@2.0.1 | | `-- is-extglob@1.0.0 | +-- path-is-absolute@1.0.1 | `-- readdirp@2.1.0 | +-- minimatch@3.0.3 | | `-- brace-expansion@1.1.6 | | +-- balanced-match@0.4.2 | | `-- concat-map@0.0.1 | `-- set-immediate-shim@1.0.1 `-- webpack-core@0.6.8 +-- source-list-map@0.1.6 `-- source-map@0.4.4 `-- amdefine@1.0.0 npm WARN optional Skipping failed optional dependency /chokidar/fsevents: npm WARN notsup Not compatible with your operating system or architecture: fsevents@1.0.14 npm WARN w1@1.0.0 No description npm WARN w1@1.0.0 No repository field. >
這時候,你再檢查一下 package.json 文件,它應(yīng)該多了三行。
{ "name": "w1", "version": "1.0.0", "description": "", "main": "index.js", "dependencies": {}, "devDependencies": { "webpack": "^1.13.2" }, "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC" }
4. Hello, Webpack
4.1 打包普通腳本文件
寫一段普通的腳本,例如,一個 Hellowrold 腳本。當(dāng)然了,這里應(yīng)該是 Hello,Webpack.
function hello(){ alert("Hello, Webpack!"); }
保存到你的項目根目錄中,文件名就叫 hello.js
4.2 創(chuàng)建 Webpack 配置文件
Webpack 根據(jù)配置文件的配置來完成打包,默認(rèn)的配置文件名稱是 webpack.config.js。
Webpack 的工作很簡單,就是打包,你需要告訴它打包的內(nèi)容,還有輸出到哪里。entry 就是入口,顯然 output 就是輸出。
我們讓 Webpack 將 hello.js 文件打包后輸出到 bundle.js 文件中。
module.exports = { // 入口 entry: "./hello.js", // 輸出的文件名 output: { filename: 'bundle.js' } };
在命令窗口,輸入 webpack 回車執(zhí)行。應(yīng)該會看到如下的輸出。
> webpack Hash: 05c39d9076887c35f015 Version: webpack 1.13.2 Time: 59ms Asset Size Chunks Chunk Names bundle.js 1.44 kB 0 [emitted] main [0] ./hello.js 51 bytes {0} [built] >
默認(rèn)的入口文件名為 index.js,如果你將 hello.js 改名為 index.js,還可以直接使用目錄名,不用提供文件名。
module.exports = { // 入口,默認(rèn)入口文件名為 index.js entry: ".", // 輸出的文件名 output: { filename: 'bundle.js' } };
生成的 bundle.js 文件內(nèi)容為
/******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ exports: {}, /******/ id: moduleId, /******/ loaded: false /******/ }; /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ // Flag the module as loaded /******/ module.loaded = true; /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ // Load entry module and return exports /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ function(module, exports) { function hello(){ alert("Hello, Webpack!"); } /***/ } /******/ ]);
最后就是我們的腳本。
4.2 將腳本嵌入到網(wǎng)頁中
剛剛只是一段腳本,還需要放到網(wǎng)頁中才能執(zhí)行。我們可以安裝一個自動幫我們生成宿主網(wǎng)頁的 webpack 插件 html-webpack-plugin 來幫助我們。
npm install html-webpack-plugin --save-dev
應(yīng)該會看到如下的輸出。
> npm install html-webpack-plugin --save-dev w1@1.0.0 w1 `-- html-webpack-plugin@2.24.0 +-- bluebird@3.4.6 +-- html-minifier@3.1.0 | +-- change-case@3.0.0 | | +-- camel-case@3.0.0 | | +-- constant-case@2.0.0 | | +-- dot-case@2.1.0 | | +-- header-case@1.0.0 | | +-- is-lower-case@1.1.3 | | +-- is-upper-case@1.1.2 | | +-- lower-case@1.1.3 | | +-- lower-case-first@1.0.2 | | +-- no-case@2.3.0 | | +-- param-case@2.1.0 | | +-- pascal-case@2.0.0 | | +-- path-case@2.1.0 | | +-- sentence-case@2.1.0 | | +-- snake-case@2.1.0 | | +-- swap-case@1.1.2 | | +-- title-case@2.1.0 | | +-- upper-case@1.1.3 | | `-- upper-case-first@1.1.2 | +-- clean-css@3.4.20 | | +-- commander@2.8.1 | | `-- source-map@0.4.4 | +-- commander@2.9.0 | | `-- graceful-readlink@1.0.1 | +-- he@1.1.0 | +-- ncname@1.0.0 | | `-- xml-char-classes@1.0.0 | +-- relateurl@0.2.7 | `-- uglify-js@2.7.3 | `-- async@0.2.10 +-- lodash@4.16.4 +-- pretty-error@2.0.2 | +-- renderkid@2.0.0 | | +-- css-select@1.2.0 | | | +-- boolbase@1.0.0 | | | +-- css-what@2.1.0 | | | +-- domutils@1.5.1 | | | | `-- dom-serializer@0.1.0 | | | | +-- domelementtype@1.1.3 | | | | `-- entities@1.1.1 | | | `-- nth-check@1.0.1 | | +-- dom-converter@0.1.4 | | | `-- utila@0.3.3 | | +-- htmlparser2@3.3.0 | | | +-- domelementtype@1.3.0 | | | +-- domhandler@2.1.0 | | | +-- domutils@1.1.6 | | | `-- readable-stream@1.0.34 | | | `-- isarray@0.0.1 | | +-- strip-ansi@3.0.1 | | | `-- ansi-regex@2.0.0 | | `-- utila@0.3.3 | `-- utila@0.4.0 `-- toposort@1.0.0 npm WARN optional Skipping failed optional dependency /chokidar/fsevents: npm WARN notsup Not compatible with your operating system or architecture: fsevents@1.0.14 npm WARN w1@1.0.0 No description npm WARN w1@1.0.0 No repository field. >
這說明這個插件安裝好了。
配置 Webpack 使用這個插件,幫助我們生成一個網(wǎng)頁,然后將打包的腳本自動插入到這個網(wǎng)頁中。
var HtmlwebpackPlugin = require('html-webpack-plugin'); module.exports = { // 入口 entry: ".", // 輸出的文件名 output: { filename: 'bundle.js' }, // 添加我們的插件 會自動生成一個html文件 plugins: [ new HtmlwebpackPlugin({ title: 'Hello Webpack' }) ] };
其實,這個配置文件就是一段程序,注意第一行,一定要加上。
重新執(zhí)行 webpack 命令。你會看到多生成了一個名為 index.html 的網(wǎng)頁。
> webpack Hash: 05c39d9076887c35f015 Version: webpack 1.13.2 Time: 560ms Asset Size Chunks Chunk Names bundle.js 1.44 kB 0 [emitted] main index.html 184 bytes [emitted] [0] ./index.js 51 bytes {0} [built] Child html-webpack-plugin for "index.html": + 3 hidden modules >
打開這個網(wǎng)頁,檢查插入的腳本引用。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Hello Webpack</title> </head> <body> <script type="text/javascript" src="bundle.js"></script></body> </html>
5. 總結(jié)
Webpack 是一個基于 NodeJs 的打包工具,我們可以使用它幫助我們將腳本打包,它還可以幫助我們生成宿主網(wǎng)頁,并自動將打包之后的腳本嵌入到這個網(wǎng)頁中。