這兩週一直想寫webpack的知識點,卻發現webpack其實要將webpack說的具體內容仍是挺多的。並且稀土掘金上一搜webpack有好多人都有去寫webpack的知識點,因此本文中再也不去重複別人的東西了,就簡單記錄一下我對webpack的理解。並按照老規矩附上demo以及我收藏的幾篇不錯的webpack入門文章以供學習參考~css
webpack是一個模塊打包工具。
用vue項目來舉例:瀏覽器它是隻認識js,不認識vue的。而咱們寫的代碼後綴大可能是.vue的,在每一個.vue文件中均可能html、js、css甚至是圖片資源;而且因爲組件化,這些.vue文件之間還有錯綜複雜的關係。因此項目要被瀏覽器識別,咱們就要使用webpack將它們打包成js文件以及相應的資源文件。
或者這麼理解,咱們以vue項目的形式編寫項目邏輯,瀏覽器以他理解的方式來運行項目。webpack把咱們的vue項目想表達的全部意圖傳遞給瀏覽器讓瀏覽器去運行。
PS:webpack功能不止於此,但這個功能是讓咱們項目能跑起來的必要條件!(我的理解,若有錯誤,還請批評指正)html
這裏咱們來理解下webpack是如何打包的~(轉譯會在loaders中提到)。首先咱們寫兩個最簡單的js
hello.js前端
console.log("hello~~")
app.jsvue
console.log("hello app"); require("./hello.js")
app.js
中導入了hello.js
,它們之間有導入關係。咱們假如直接將app.js
放到html中是會報錯的。node
hello app Uncaught ReferenceError: require is not defined at app.js:2
若是咱們要維持這種關係咱們就必須使用打包工具進行打包。在命令行中輸入:webpack
// 安裝webpack $ npm install webpack -g // 打包app.js $ webpack app.js bundle.js
而後咱們會發現項目中多了一個bundle.js文件,咱們在html中導入這個js文件。
index.htmlios
<!DOCTYPE html> <html> <head> <title>demo01</title> </head> <body> <h1>demo01</h1> <script src="bundle.js"></script> </body> </html>
最後輸出正確結果git
hello app hello~~
webpack.config.js文件是webpack的默認配置文件。以前咱們使用命令行$ webpack entry.js output.js
來實現打包,其實webpack能夠有更多的打包配置,這些配置都是在webpack.config.js中完成的。下面是一個簡單的webpack.config.js。github
const webpack = require("webpack") module.exports = { entry: { entry: "./app/entry.js", }, output: { path: __dirname + "/dist", filename: 'bundle.js', }, module: { loaders: [ { test: /\.js$/, loader: 'babel', exclude: /node_modules/ }, ] } }
我的以爲這三個東西是最最重要的了,因此必須單獨說說這三個配置。其餘配置均可以去查閱資料慢慢來。web
entry是配置webpack的入口文件,上面的代碼中咱們將app目錄下的entry.js做爲入口文件。webpack會將與entry.js有關的資源都進行打包。
output是出口文件,即打包好的文件的存放地址和文件名。
這裏有幾種文件的輸入輸出狀況。引用自Webpack 2 入門教程。
const webpack = require("webpack"); module.exports = { context: __dirname + "/src", entry: { app: "./app.js", }, output: { path: __dirname + "/dist", filename: "[name].bundle.js", }, };
const webpack = require("webpack"); module.exports = { context: __dirname + "/src", entry: { app: ["./home.js", "./events.js", "./vendor.js"], }, output: { path: __dirname + "/dist", filename: "[name].bundle.js", }, };
const webpack = require("webpack"); module.exports = { context: __dirname + "/src", entry: { home: "./home.js", events: "./events.js", contact: "./contact.js", }, output: { path: __dirname + "/dist", filename: "[name].bundle.js", }, };
你們能夠動手實踐一下,很好理解。打包出來的單個或者多個文件直接能夠在html中使用。
<script src="./dist/entry.js"></script>
loader是webpack的加載器,能夠幫咱們處理各類非js文件。如css樣式,vue、jsx、weex等後綴的代碼,JPG、PNG圖片等。因此咱們通常會在package.json中看到各類*-loader。這些就是各種資源的loader加載器。
在module的loaders數組中能夠有多個對象,每一個對象就是一個加載器。下面是babel-loader的最簡單配置方式
module: { loaders: [ { test: /\.js$/, loader: 'babel', }, ] }
對象中的test是正則表達式,用於搜索後綴爲.js的文件。loader是所用加載器名稱。
下面咱們來一步步使用babel-loader將ES6語法用於項目中。
webpack打包的文件默認是不支持ES6的,咱們須要用babel轉譯。
這個配置其實我是抄的vue-cli,我的對babel用法還不是很熟。
在package.json中添加依賴。
"devDependencies": { ... "babel-core": "^6.22.1", "babel-loader": "^6.2.10", "babel-plugin-transform-runtime": "^6.22.0", "babel-preset-es2015": "^6.0.0", "babel-preset-stage-2": "^6.0.0", "babel-register": "^6.0.0", "webpack": "^1.14.0" ... }
npm安裝
$ npm install
module: { loaders: [ { test: /\.js$/, loader: 'babel', }, ] }
在項目根目錄下添加.babelrc文件,文件內容爲
{ "presets": ["es2015", "stage-2"], "plugins": ["transform-runtime"], "comments": false }
import good from './good.js'
說了這麼多,個人最終目的仍是爲了學習Vue.js。因此在對webpack有了必定的理解以後,就發現其實vue-cli並非那麼深不可測。
build —— 項目構建文件夾
build.js —— 打包構建腳本(npm run build)
check-versions.js —— npm和node版本的查詢
dev-client.js ——
dev-server.js —— 開發調試腳本(npm run dev)
utils.js —— 工具類
webpack.base.config.js —— Webpack配置文件
webpack.dev.config.js —— 開發版本Webpack配置文件,與webpack.base.config.js合併成完整的配置文件。
webpack.prod.config.js —— 生產版本Webpack配置文件,與webpack.base.config.js合併成完整的配置文件。
config —— 配置文件夾,保存有各類配置參數(文件路徑、服務器端口、功能開關)
src —— 代碼文件夾
static
.gitkeep —— 做用是將文件所在文件夾保留在git版本控制中。文件類型和.gitignore差很少。
.babelrc —— babel配置文件
.editorconfig —— 編輯配置,確保使用各類編輯器時能有相同的編輯格式。
.gitignore —— git忽略文件
index.html —— 頁面,最終顯示在這個html中
package.json —— npm配置文件,包含了項目的信息、腳本、依賴庫等重要信息。
理解完vue-cli的某些功能後,不難發現咱們本身也能夠搭建簡易的vue-cli了。
官方的腳手架中除了有webpack打包,還包含了node腳本、開發和生產模式的切換、ESLint配置等功能。咱們暫時不須要,將項目簡化來更好的理解webpack。
讓咱們來本身創建一個cli,首先建立一個空文件夾。
$ mkdir demo05 $ cd demo05
初始化npm
$ npm init
而後複製vue-cli中的依賴庫到package.json中(直接複製啦,具體依賴庫的做用就不提啦~以後會寫博客補上的)。
"dependencies": { "vue": "^2.1.0" }, "devDependencies": { "autoprefixer": "^6.4.0", "babel-core": "^6.0.0", "babel-loader": "^6.0.0", "babel-plugin-transform-runtime": "^6.0.0", "babel-preset-es2015": "^6.0.0", "babel-preset-stage-2": "^6.0.0", "babel-register": "^6.0.0", "chalk": "^1.1.3", "connect-history-api-fallback": "^1.1.0", "css-loader": "^0.25.0", "eventsource-polyfill": "^0.9.6", "express": "^4.13.3", "extract-text-webpack-plugin": "^1.0.1", "file-loader": "^0.9.0", "friendly-errors-webpack-plugin": "^1.1.2", "function-bind": "^1.0.2", "html-webpack-plugin": "^2.8.1", "http-proxy-middleware": "^0.17.2", "json-loader": "^0.5.4", "semver": "^5.3.0", "opn": "^4.0.2", "ora": "^0.3.0", "shelljs": "^0.7.4", "url-loader": "^0.5.7", "vue-loader": "^10.0.0", "vue-style-loader": "^1.0.0", "vue-template-compiler": "^2.1.0", "webpack": "^1.13.2", "webpack-dev-middleware": "^1.8.3", "webpack-hot-middleware": "^2.12.2", "webpack-merge": "^0.14.1" },
這裏的webpack配置文件中的部份內容是從官方的 webpack.base.config.js
中複製出來的。正如我項目結構中所說的,vue-cli中的 webpack.base.config.js
是基礎的配置文件。vue-cli中的 webpack.dev.config.js
和 webpack.prod.config.js
分別表明了開發和生產版本的webpack配置文件,他們與 webpack.base.config.js
合併成最後的webpack配置文件。這裏咱們只要找到 webpack.base.config.js
便可。
下面是完整配置代碼。
var path = require("path") var projectRoot = path.resolve(__dirname, '../') module.exports = { // 入口文件 entry: "./src/main.js", // 輸出文件 output: { filename: "./dist/bundle.js" }, // 別名 resolve: { extensions: ['', '.js', '.vue', '.json'], fallback: [path.join(__dirname, '../node_modules')], alias: { 'vue$': 'vue/dist/vue.common.js', 'src': path.resolve(__dirname, '../src'), 'assets': path.resolve(__dirname, '../src/assets'), 'components': path.resolve(__dirname, '../src/components') } }, module: { // 加載器 loaders: [ { test: /\.vue$/, loader: 'vue' }, { test: /\.js$/, loader: 'babel', exclude: /node_modules/ }, { test: /\.json$/, loader: 'json' }, { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url', }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, loader: 'url', } ] }, }
因爲使用git、babel,因此我將vue-cli中的 .gitignore
和 .babelrc
直接複製過來。
還有,因爲懶得寫邏輯代碼,這裏我將 src
文件夾中全部內容也直接複製過來。
複製按成後進行webpack打包。
$ webpack
打包完成就會出現一個在 dist
目錄下有一個 bundle.js
文件。有了打包文件,咱們還須要建立一個 index.html
來顯示效果,這個以後再說。
因此,最後的項目結構以下圖
如今,到了呈現效果的時候了。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Demo3</title> </head> <body> <div id="app"> </div> <script src="./dist/bundle.js"></script> </body> </html>
很簡單,建立一個id爲app的div元素用於顯示Vue組件內容,而後將打包好的bundle.js引用進去。
如今,到項目目錄中找到 index.html
頁面,瀏覽器打開就能夠看到效果啦~
注:簡易cli項目的源碼在 VueStudyDemosWebpackDemosdemo5中
這裏推薦一下我學習webpack中發現的一些好的網站,分享一下。
https://github.com/webpack-ch...
http://blog.guowenfh.com/2016...
拖了一個春節,終於把webpack的博客給寫出來了。感受在寫完博客以後對webpack的理解深入了許多,再次證實了「教是最好的學」這個理論。
新的一年,我要堅持好好寫博客,享受分享帶來的快樂。
以後計劃學習一下eslint以及一些測試工具。而後試着用element和mint作兩個小demo分享出來。而後瞭解一下node的相關知識。
做者最近正在惡補Vue的各類知識,但願可以系統的掌握Vue的開發知識。有興趣的同窗能夠查看以前發佈的文章:
Vue.js學習系列一 —— vue-router2學習實踐筆記(附DEMO)
Vue.js學習系列二 —— vuex學習實踐筆記(附DEMO)
Vue.js學習系列三——axios和網絡傳輸相關知識的學習實踐
Vue.js學習系列四——Webpack打包工具的使用
Vue.js學習系列五 —— 從VUE-CLI來聊聊ESLint
本文源碼已收入到GitHub中,以供參考,固然能留下一個star更好啦^-^。
https://github.com/violetjack...
VioletJack,移動、前端工程師,兩年移動端工做經驗、一年前端工做經驗。現專一於移動前端的學習和開發。擅長Android開發和Vue前端開發。會按期產出關於Android、Vue、移動前端相關的博文。歡迎你們關注我,我會用心維護和經營好博客,多產出高質量文章。同時也但願我所寫的東西能夠幫到有須要的朋友。
新浪微博: http://weibo.com/u/2640909603
掘金:https://gold.xitu.io/user/571...
CSDN: http://blog.csdn.net/violetja...
簡書: http://www.jianshu.com/users/...
Github: https://github.com/violetjack