一項技術、一個工具的出現,確定是爲了解決問題的。那麼,webpack 是爲了解決什麼問題?答案是:文件依賴管理。瀏覽器端的 Js, 出於安全的考慮,對本地文件沒有操做權限,不能引用其它 js, css 等文件。而 webpack 就是用來解決這個問題的,讓你的項目能夠很好地分文件、分模塊,並且它對外部文件的引入同時支持 cmd, amd 和 commondJs 這三種形式,夠有誠意。
或許你要說了,解決文件依賴,早在 require.js 和 sea.js 的時候,都已經解決了呀!那麼,webpack 在這方面,有哪些新的突破:css
這個時候,是否是很想唱一下王力宏的《惟一》:肯定你就是個人惟一!
OK,進入正題。html
目前,咱們的項目目錄結構是這樣的:vue
webpack_demo |--src | |--pages | | |--index | | | |--index.js |--views_dev | |--index.html |--webpack.config.js |--package.json
在項目的根目錄執行:node
$ npm init // 生成項目依賴文件配置 package.json $ npm install webpack -g // 全局安裝webpack $ touch webpack.config.js // 在項目根目錄下,新建 webpack.config.js 文件
而後,在如下3個文件,輸入內容:react
頁面 HTML 文件jquery
// views_dev/index.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>首頁</title> </head> <body> <div>哈嘍,world</div> <script src="../asset/dev/main.js"></script> </body> </html>
頁面引用的 js 文件webpack
// src/pages/index/index.js console.log('I am in index/index.js, haha4');
webpack 打包配置git
// webpack.config.js module.exports = { // 入口:要進行處理的實例(js) entry: './src/pages/index/index.js', // 出口:輸出配置 output: { // 輸出到哪一個目錄 path: './asset/dev/', // 靜態資源的引用路徑 publicPath: '/asset/dev/', // 實例最終輸出的名字 filename: '[name].js' } };
運行 webpack 命令,進行打包。github
$ webpack
而後,搞定了,此時用瀏覽器打開 views_dev/index.html
這個文件,你會發現,打包成功了!web
好的,你入門了,哈哈!接下去,我會詳細介紹單個頁面打包、多個頁面打包,以及最後的發佈上線。Now, go ~
這裏,你將學到:
如今,咱們的項目目錄,是這樣:
webpack_demo |--src | |--pages | | |--index | | | |--index.js | | | |--test.js | | | |--index.css | |--plugins | | |--dialog | | | |--dialog.css | | | |--dialog.js |--views_dev | |--index.html |--webpack.config.js |--package.json
經過相對路徑
如今,咱們要在 src/pages/index.js
裏面引入 src/pages/test.js
文件。這樣作就能夠了:
var Test = require('./test.js');
你也許會問,此時,var Test
這個變量,獲得的是什麼?換個說法,怎麼控制 test.js
被導出到外部的內容。答案是:經過 module.exports
. 例如:
// index/test.js var str = "I am in test.js"; module.exports = str;
那麼,require('./test.js')
的值就是 "I am in test.js" 這個字符串。module.exports
能夠導出任何值。好比,咱們要導出 Object.
module.exports = { aa: 'axxx', b: function() {} };
經過別名或模塊
若是隻能使用相對路徑,那 webpack
就太不靠譜了。由於將有可能出現這樣 ../../../../libs/libs-tost/toast.js
, 啊,想死!那麼,怎麼經過別名引入文件呢?假如,咱們想引入 src/plugins/dialog/dialog.js
這個彈窗。
在 webpack.config.js
中,配置別名
// webpack.config.js module.exports = { resolve: { // 定義別名 alias: { plugins: 'D:/your/path/webpack_demo/src/plugins', // 別名能夠是目錄 myDialog: 'D:/your/path/webpack_demo/src/plugins/dialog/dialog.js' // 也能夠是文件 } } }
可使用了
// src/index/index.js var Dialog = require('plugins/dialog/dialog.js'); // 方式一 var Diaglog = require('myDialog'); // 方式二
說明:require(TagPath)
的 TagPath
若是以單詞開頭,將被認爲是模塊匹配,它會去找 node_modules
和 resolve.alias
下的模塊(或別名)。以方式一爲例,它的TagPath
是以 plugins
開頭(注意下:/plugins
和 ./plugins
都不叫以單詞開頭),因此能夠順利匹配到 resolve.alias.plugins
. 在實際應用中,你常常會看到 require('jquery')
, require('vue')
, require('react')
, 這些就是匹配到 node_modules
下已安裝的模塊。
webpack
的強大之處是,它容許你引入任何文件,好比:css, jpg, png. 那麼,問題來了,對於不一樣的文件,它要怎麼知道該如何分開處理呢?
// webpack.config.js module.exports = { module: { loaders: [{ test: /\.css$/, loader: 'style!css' }, { test: /\.js$/, loader: 'babel' }] } };
上面的配置是說,對於拓展名是 .css
的文件,使用加載器 style!css
(這邊中間有一個感嘆號,意思是:先是用 css 加載器處理,而後使用 style 加載器處理)。完整的寫法是:style-loader!css-loader
, 其中,-loader
能夠省略。而這裏的,style-loader
和 css-loader
就須要你 npm 安裝下了。
$ npm i style-loader -D $ npm i css-loader -D
對於其它拓展名的處理,也是用一樣的方式來處理。
你確定但願,這樣的功能。那麼,開始吧,喝杯咖啡!
$ webpack -w
就能夠開啓它的自動編譯功能。用 webpack-dev-server 實現:自動編譯 + 瀏覽器同步刷新
首先,你須要安裝 webpack-dev-server
這個包。
$ npm i webpack-dev-server -D
而後,我簡單介紹下它:webpack-dev-server 文檔
webpack.config.js
文件,來做爲 webpack
配置文件。行內參數說明:
--content-base ./
好了,那麼,啓動它吧:
$ webpack-dev-server --inline --content-base ./
而後,你在瀏覽器中,訪問 http://localhost:8080/views_dev/index.html
就會發現,你修改代碼的時候,實時編譯,而且瀏覽器同步刷新了。(不過,要補充一下,觸發 webpack 從新編譯時,才能同步刷新瀏覽器。意味着,你修改 views_dev/*.html
的 HTML 文件時,瀏覽器,不會被刷新,由於它不會觸發 webpack 從新編譯。)
如今,咱們加一點點配置,讓它支持多個頁面打包。以前,它是這樣的:
module.exports = { // 入口:要進行處理的實例(js) entry: './src/pages/index/index.js', // 出口:輸出配置 output: { // 輸出到哪一個目錄 path: './asset/dev/', // 靜態資源的引用路徑 publicPath: '/asset/dev/', // 實例最終輸出的名字 filename: '[name].js' }, // 其它配置... };
如今,咱們須要改下 entry
的配置,以下:
entry: { index: './src/pages/index/index.js', list: './src/pages/list/index.js', common: [ './src/base/base.js', './src/base/base.css' ] }
上面的配置意思是,會獨立打包3個實體。分別是 index, list, common. 知識點以下:
common
的配置。咱們通常,用來放公共基礎包。咱們看到 output.filename = [name].js
,這裏的 [name]
取自於 entry 的 key 值。意味着,他們最終打包的輸出是:
webpack_demo |--asset | |--dev | | |--index.js | | |--list.js | | |--common.js
發佈上線,須要作什麼呢?也許是這樣:
哈哈,或許你還能想到不少。我就上面4步來講下實現方式。開始以前,咱們通常會這麼作:新建一個 webpack 的配置文件,用來作上線發佈的配置。好比,咱們一樣放在根目錄下,命名 webpack.config.build.js
. 此時,你能夠這樣作:
$ webpack -p --config webpack.config.build.js
這裏的 -p
是 production 模式的意思,它會對 css, js 文件進行壓縮。後面 --config
就是指定這次運行的配置文件。
而後,咱們來解決上面的4個要求:
把靜態資源生成到一個獨立的目錄下 + md5 + css引用的資源替換
// webpack.config.build.js module.exports = { output: { path: './asset/build/', // 文件編譯輸出路徑改爲 build publicPath: 'http://yourweb.com/asset/build/', // 這裏替換成線上實際地址,能夠修改 css 中對圖片資源的引用路徑。 filename: '[name]_[hash:5].js' // 生成的文件名字,加上了5位的 hash值。固然了,位數和加hash的位置,你能夠本身定義,好比 '[name].js?[hash]'. }, // 其它配置... };
webpack -p
解決了。html-webpack-plugin
來作。或者,你對 gulp 仍是比較熟悉的話,用 gulp-prefix
來實現。這裏就不詳細寫配置了。而後,恭喜你看完了!