好久沒寫技術博客了, 原因在于最近在學習前端方面的技術, 熟悉我的同學都知道, 之前我有使用Vue搭建了一個個人簡歷, 體驗了一把最新的前端技術, 但之前我們使用的是vue-cli腳手架工具, 對于如何自己實現(xiàn)前端構建工具, 當下最為流行的就是webpack和gulp了, 之前一篇我們講了gulp, 這一篇我們來好好討論webpack.
成都創(chuàng)新互聯(lián)主要從事做網站、網站制作、網頁設計、企業(yè)做網站、公司建網站等業(yè)務。立足成都服務中方,10余年網站建設經驗,價格優(yōu)惠、服務專業(yè),歡迎來電咨詢建站服務:18982081108
說起webpack, 想必做前端的同學肯定不會陌生, 其實之前我們使用gulp構建的時候, 也使用了webpack的打包技術, 其實gulp和webpack并不是相互替代的關系, 而是相輔相成, 今天我們就來好好看看webpack的神奇之處吧.
我們學習一樣新技術, 首先肯定是從他的官方文檔入手, 當然我們要學習也是學最新版的.webpack的官方教程寫的非常好, 一步一步講的很到位, 各位同學可以直接閱讀官方文檔, 比起博客中的二手, 三手以及四手的資料, 官方文檔肯定是你更好的選擇.
這篇文章, 不是教你什么看這一篇就夠了之類的對于官方文檔拷貝的水文, 而是能讓你快速上手并且覺得所謂的webpack其實也就這么一回事, webpack你只要記住一個中心思想, 就和上面的圖示一樣, 將所有錯綜復雜的文件邏輯打包壓縮成幾個靜態(tài)資源, 不多說了, 我們還是看代碼來的實際.
webpack.config.js
對于一些拋棄jquery迎接react和vue的前端開發(fā)者來說, webpack雖然可能自己沒有寫過, 但看總是看過的吧, 一般來說, 都會有一個webpack.config.js
的webpack配置文件.下面的代碼就是一個簡單的webpack的配置, 麻雀雖小五臟俱全.
var debug = process.env.NODE_ENV !== "production"; //是否是測試環(huán)境 var webpack = require('webpack'); //導入webpack包 var path = require('path'); module.exports = { //導出 webpack固定寫法 context: path.join(__dirname), devtool: debug ? "inline-sourcemap" : null, //是否使用map工具, 用于瀏覽器debug entry: "./src/js/root.js", //打包的實體 module: { loaders: [ //加載的配置 { test: /\.js?$/, exclude: /(node_modules)/, loader: 'babel-loader', query: { presets: ['react', 'es2015'], //添加預處理器 plugins: ['react-html-attrs'], //添加組件的插件配置 } }, { test: /\.css$/, loader: 'style-loader!css-loader' }, { test: /\.less$/, loader: "style!css!less" } ] }, output: { //輸出的路徑及文件名 path: __dirname, filename: "./src/bundle.js" }, plugins: debug ? [] : [ //一些插件 new webpack.optimize.DedupePlugin(), new webpack.optimize.OccurenceOrderPlugin(), new webpack.optimize.UglifyJsPlugin({ mangle: false, sourcemap: false }), ], };
webpack主要包括entry, module, output, plugins
四大類, 官方文檔說的已經很清楚了, 想要進一步的學習,請翻閱官方文檔, 如果不想折騰直接拷貝上述代碼即可.
相較gulp, webpack在打包方面更為精簡, 這也是流行的原因吧, 但光看上面的文件, 的確也是簡單, 但是還有進一步改善的空間.
package.json
對于npm的介紹我就不多說了, 我們直接來看文件.
{ "name": "webpack", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { //命令行工具 "test": "echo \"Error: no test specified\" && exit 1", "watch": "webpack --progress --watch", "start": "webpack-dev-server --open --config webpack.dev.js", "build": "webpack --config webpack.prod.js" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { //開發(fā)環(huán)境依賴 "babel-loader": "^7.1.2", "clean-webpack-plugin": "^0.1.16", "css-loader": "^0.28.7", "csv-loader": "^2.1.1", "file-loader": "^0.11.2", "html-webpack-plugin": "^2.30.1", "json-loader": "^0.5.7", "lodash": "^4.17.4", "style-loader": "^0.18.2", "uglifyjs-webpack-plugin": "^0.4.6", "webpack": "^3.6.0", "webpack-dev-middleware": "^1.12.0", "webpack-dev-server": "^2.8.2", "webpack-merge": "^4.1.0", "xml-loader": "^1.2.1" }, "dependencies": { //生產環(huán)境依賴 "babel-plugin-import": "^1.5.0", "babel-plugin-react-html-attrs": "^2.0.0", "babel-preset-es2015": "^6.24.1", "babel-preset-react": "^6.24.1", "babelify": "^7.3.0", "react": "^15.6.1", "react-dom": "^15.6.1", "react-mixin": "^4.0.0", "react-router": "^4.2.0" } }
命令行工具就是npm run build等于執(zhí)行了webpack --config webpack.prod.js, 而npm start 等于執(zhí)行了webpack-dev-server --open --config webpack.dev.js.簡單易懂吧.
在項目依賴中, 哦們加了很多的插件和loader, 都是用來搭建webpack的, 官方文檔的教程中都會講到, 值得注意的就是webpack-merge這個包, 這個包可以讓我們生產環(huán)境和開發(fā)環(huán)境很好的隔離配置, 我們看看怎么做呢?
首先我們需要將之前的webpack.config.js分成三個文件 --- webpack.common.js, webpack.dev.js, webpack.prod.js.
webpack.common.js
這個是webpack的共同配置, 總體和之前看到的大同小異, 我們主要是導入了兩個插件, 一個是清除插件, 一個是創(chuàng)建html的插件.
const path = require('path'); const webpack = require('webpack'); const CleanWebpackPlugin = require('clean-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './src/index.js', plugins: [ new CleanWebpackPlugin(['dist']), new HtmlWebpackPlugin({title: 'webpack'}), new webpack.HashedModuleIdsPlugin() ], output: { filename: '[name].[chunkhash].js', path: path.resolve(__dirname, 'dist') }, module: { rules: [ { test: /\.js?$/, exclude: /(node_modules)/, loader: 'babel-loader', query: { presets: [ 'react', 'es2015' ], plugins: ['react-html-attrs'] } }, { test: /\.css$/, use: ['style-loader', 'css-loader'] }, { test: /\.(png|svg|jpg|gif)$/, use: ['file-loader'] }, { test: /\.(woff|woff2|eot|ttf|otf)$/, use: ['file-loader'] }, { test: /\.(csv|tsv)$/, use: ['csv-loader'] }, { test: /\.xml$/, use: ['xml-loader'] } ] } };
rules
配置中我們也就是將一些可能用到的文件也配置到webpack中來, babel-loader
這種如果要講還可以再開一篇, 其實就是個js的兼容性工具, 這樣理解就可以了.
webpack.dev.js
webpack開發(fā)環(huán)境的配置, 非常簡單, 就是用了之前講的webpack-merge工具, 就和git一樣, 合并了webpack.common.js的配置外新加了可以進行調試的inline-source-map工具, 以及熱更新的內容索引.
const merge = require('webpack-merge'); const common = require('./webpack.common.js'); module.exports = merge(common, { devtool: 'inline-source-map', devServer: { contentBase: './dist' } });
webpack.prod.js
webpack生產環(huán)境的配置, 新加了一個壓縮插件以及環(huán)境配置的插件, 這里的開發(fā)工具和開發(fā)還款下的有所不同, 具體可直接看官方文檔.
const webpack = require('webpack'); const merge = require('webpack-merge'); const UglifyJSPlugin = require('uglifyjs-webpack-plugin'); const common = require('./webpack.common.js'); module.exports = merge(common, { devtool: 'source-map', plugins: [ new UglifyJSPlugin({sourceMap: true}), new webpack.DefinePlugin({ 'process.env': { 'NODE_ENV': JSON.stringify('production') } }) ] });
terminal
這樣我們就配置完成啦, 我們在終端上輸入看下效果:
cd ../ && npm i
首先我們進入到目錄下并進行node包的安裝.
npm run build
MacBook-Pro-15:webpack zhushuangquan$ npm run build > webpack@1.0.0 build /Users/zhushuangquan/Documents/code/webpack > webpack --config webpack.prod.js clean-webpack-plugin: /Users/zhushuangquan/Documents/code/webpack/dist has been removed. Hash: 85b65f54ef1436b295a5 Version: webpack 3.6.0 Time: 1148ms Asset Size Chunks Chunk Names main.014ac9aa420264da48eb.js 671 bytes 0 [emitted] main main.014ac9aa420264da48eb.js.map 6.47 kB 0 [emitted] main index.html 197 bytes [emitted] [lVK7] ./src/index.js 184 bytes {0} [built] Child html-webpack-plugin for "index.html": 1 asset [3IRH] (webpack)/buildin/module.js 517 bytes {0} [built] [DuR2] (webpack)/buildin/global.js 509 bytes {0} [built] + 2 hidden modules
我們可以看到已經打包好的文件:
main.014ac9aa420264da48eb.js
!function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var t={};n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},n.p="",n(n.s="lVK7")}({lVK7:function(e,n,t){"use strict";document.body.appendChild(function(){var e=document.createElement("div");return e.innerHTML="Hello webpack",e}())}}); //# sourceMappingURL=main.014ac9aa420264da48eb.js.map
我們可以看到在webpack的打包和壓縮下, 代碼已經基本不可讀了. 所以我們需要加上之前的調試插件, 以便生產環(huán)境出現(xiàn)bug后的補救.
npm start
MacBook-Pro-15:webpack zhushuangquan$ npm start > webpack@1.0.0 start /Users/zhushuangquan/Documents/code/webpack > webpack-dev-server --open --config webpack.dev.js clean-webpack-plugin: /Users/zhushuangquan/Documents/code/webpack/dist has been removed. Project is running at http://localhost:8080/ webpack output is served from / Content not from webpack is served from ./dist webpack: wait until bundle finished: / Hash: 06f20ec519d58fbd5c28 Version: webpack 3.6.0 Time: 1460ms Asset Size Chunks Chunk Names main.5eb4d4e3f458c49658a2.js 852 kB 0 [emitted] [big] main index.html 197 bytes [emitted] [6Um2] (webpack)/node_modules/url/util.js 314 bytes {0} [built] [8o/D] (webpack)-dev-server/client/overlay.js 3.71 kB {0} [built] [HPf+] (webpack)/node_modules/url/url.js 23.3 kB {0} [built] [Lx3u] (webpack)/hot/log.js 1.04 kB {0} [optional] [built] [Sj28] (webpack)-dev-server/node_modules/strip-ansi/index.js 161 bytes {0} [built] [TfA6] (webpack)/hot nonrecursive ^\.\/log$ 170 bytes {0} [built] [U2me] (webpack)/hot/emitter.js 77 bytes {0} [built] [V3KU] (webpack)-dev-server/client/socket.js 1.04 kB {0} [built] [cMmS] (webpack)-dev-server/client?http://localhost:8080 7.27 kB {0} [built] [gqsi] (webpack)-dev-server/node_modules/loglevel/lib/loglevel.js 7.74 kB {0} [built] [0] multi (webpack)-dev-server/client?http://localhost:8080 ./src/index.js 40 bytes {0} [built] [gt+Q] (webpack)-dev-server/node_modules/ansi-regex/index.js 135 bytes {0} [built] [lVK7] ./src/index.js 184 bytes {0} [built] [p7Vd] (webpack)/node_modules/punycode/punycode.js 14.7 kB {0} [built] [pEPF] (webpack)/node_modules/querystring-es3/index.js 127 bytes {0} [built] + 73 hidden modules Child html-webpack-plugin for "index.html": 1 asset [3IRH] (webpack)/buildin/module.js 517 bytes {0} [built] [DuR2] (webpack)/buildin/global.js 509 bytes {0} [built] [M4fF] ./node_modules/lodash/lodash.js 540 kB {0} [built] [a/t9] ./node_modules/html-webpack-plugin/lib/loader.js!./node_modules/html-webpack-plugin/default_index.ejs 538 bytes {0} [built] webpack: Compiled successfully.
我們可以看到打開了一個內容為Hello webpack的網頁在8080端口, 當我們修改了文件時候網頁會自動刷新.
知識點:
回到我們剛才的package.json的命令行配置來看.
"scripts": { //命令行工具 "test": "echo \"Error: no test specified\" && exit 1", "watch": "webpack --progress --watch", "start": "webpack-dev-server --open --config webpack.dev.js", "build": "webpack --config webpack.prod.js" },
以上就是webpack的使用及邏輯, 并沒有想象中的復雜吧, 甚至可以說是簡單, 實測一天即可入門webpack.
由于webpack的配置是固定代碼, 我已經打包上傳github, 需要的同學可以進行下載.
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。