這篇文章是我在學習過程當中對本身的一個記錄和總結,也但願能夠幫助到和我當初一樣對webpack有困惑的小夥伴javascript
我在自學webpack時也參考了不少大神的文章,參考的帖子太多就不一一謝過了,再次感謝各位大神的幫助css
文章中的每一個例子,我都是親自測試過的,若是哪一個地方出現筆誤等問題還請你們批評,我會及時改正html
本文使用的webpack版本是V3.8.1前端
現現在前端主流的三種框架VueJs、ReactJs、AngularJs都推薦與webpack共同使用,因此無論你是哪一種技術路線都不得不去學習瞭解webpack。那麼webpack究竟是何方神聖?vue
官方說法是webpack是一個模塊打包機,我我的理解是它能夠把咱們在開發環境下的代碼以及依賴文件等打包成在生產環境下能夠直接使用的文件。也能夠把一些瀏覽器不能直接運行的文件進行轉化,好比是css、less、scss等。同時webpack也能夠對代碼進行優化,好比壓縮、合併、文件緩存等等。在項目中咱們只須要把相應的配置文件配置好,那麼接下來的工做就均可以交給webpack這個全能大神去完成了。java
英文: http://webpack.js.org/node
中文:https://doc.webpack-china.org/react
Github:https://github.com/webpack/we...jquery
npm install –g webpack
查看版本號webpack
webpack -v
注意:全局安裝並不推薦,由於全局安裝之後版本就固定了,好比當前你全局安裝了V3.8.1這個版本的webpack,若是你須要運行一個比較早期版本的項目,好比webpack2的項目,就會有問題。另外,若是當前項目你使用V3.8.1版本寫的,若是有一天webpack的版本升級了,好比升級到了V4.X,那麼你以前的項目頗有可能就跑不起來了。因此並不建議全局安裝,而是建議項目安裝。
進入項目所在目錄:
npm init npm install --save-dev webpack
注意:
npm init 命令的目的是生成
package.json
文件mac須要在命令前面加:
sudo
若是npm命令安裝慢,可使用
cnpm(https://npm.taobao.org/)
或者是yarn(https://yarnpkg.com/zh-Hans/
項目安裝的話,
webpack -v
命令是查看不了版本號的,由於項目安裝時webpack
是被安裝到node_modules
裏面的
初學者會有一個疑問,爲何有的時候安裝依賴包的時候是--save-dev
,而有的時候是--save
,這兩個有什麼區別呢?何時包含dev
呢?
這就須要搞清楚一個概念:開發模式
和 生產模式
。
項目在開發編碼過程當中還未上線使用就屬於開發模式,該模式下代碼不須要壓縮、合併等。好比編寫可使用sass進行css預處理,使用ES6的語法來編寫js代碼。在開發模式下依賴的包安裝的時候就須要使用--save-dev
,dev
表示開發的意思,使用--save-dev
安裝的依賴包,會安裝在package.json
的devDependencies
中,這些依賴包只在開發時候會使用到,在上線生成環境下就不須要了。
項目已經開發測試完成須要打包上線進行運營了,這時候就屬於生產模式,改模式下的文件須要是最終瀏覽器能夠直接解析的文件,不能再用如.scss
、.vue
、.jsx
等這樣的文件了。在生產模式下依賴的包安裝的時候就須要使用--save
,使用--save
安裝的依賴包,會安裝在package.json
的dependencies
中,這些依賴包是最終在上線時候使用到的,好比jquery.js
、vue.js
等。
你們在開發過程當中安裝每一個依賴包的時候,都必定先考慮這個包是隻有開發模式下能用到,仍是在生產模式下也須要用到,其實你們按照這個思路把下面的文章都看完,應該就能夠對
--save-dev
和--save
有一個本身的理解了
無論學習什麼語言或工具,Hello World都是必不可少的。
src:存放開發環境下的文件,也就是咱們平時寫的代碼都在這裏面
dist:存放生產環境下的文件,也就是打包後的文件,項目上線時把
dist
文件夾中的內容拷貝到服務器上就可使用了node_modules:是自動生成的存放依賴包的文件夾,使用
npm install
命令安裝依賴包
在src目錄下,新建文件helloworld.js
alert('Hello World!');
在src同級目錄下,新建文件webpack.config.js
const path = require('path'); module.exports = { //入口文件的配置項 entry: { hello: './src/helloworld.js' }, //出口文件的配置項 output: { path: path.resolve(__dirname, 'dist'), //[name]對應的是entry裏面的屬性名,固然也能夠指定打包後的文件名稱 filename: '[name].js' }, //模塊,loader都是在這裏面配置 module: {}, //插件 plugins: [] };
在webpack中,最重要的就是webpack.config.js文件,幾乎全部的配置項都須要在該文件中配置,該文件中最重要的四項分別是:entry(入口)、ouput(出口)、module(模塊)、plugins(插件)。
path.resolve(__dirname, 'dist')是取到當前項目的路徑下的dist文件夾,是nodejs的語法。
配置好webpack.config.js
文件後,須要在package.json
中配置scripts
,之因此要配置build
,是由於咱們的webpack
並非全局安裝的,而是項目安裝的,項目安裝的話webpack命令就被安裝到了node_modules
下面,因此須要配置才能找到該命令。
"scripts": { "build": "webpack --watch" }
執行命令進行打包:
npm run build
打包成功後,就會在dist
文件夾下,自動生成hello.js
文件。
--watch
能夠實時監控改變自動打包
watchOptions: { // 檢測時間間隔 poll : 1000, // 防止重複導報,500毫秒之內不在重複打包 aggregeateTimeout: 500, // 忽略的文件夾 ignored: /node_modules/ }
在webpack裏能夠配置服務,這樣的好處是頁面再也不使用本地協議打開,而是經過服務打開,這樣ajax等就能夠正常使用了。同時,當咱們修改代碼並保存時,能夠實時更新到頁面上,提升開發效率。
在webpack.config.js文件中,在與entry等同級配置下增長devServer
配置
const path = require('path'); module.exports = { //入口文件的配置項 entry: { hello: './src/helloworld.js' }, //出口文件的配置項 output: { path: path.resolve(__dirname, 'dist'), filename: '[name].js' }, //模塊,loader都是在這裏面配置 module: {}, //插件 plugins: [], devServer: { //設置目錄結構 contentBase: path.resolve(__dirname, 'dist'), //服務器的IP地址 host: '127.0.0.1', //服務端壓縮是否開啓 compress: true, //服務端口號 port: 8081 } };
在package.json
文件中進行配置
"scripts": { "build": "webpack --watch", "server": "webpack-dev-server" }
這樣的話就能夠經過npm run server
來開啓服務了,在地址欄裏就能夠根據devServer
裏的配置信息來訪問你的網站了,好比按照個人配置的話我須要在瀏覽器地址欄輸入:http://127.0.0.1:8081
來訪問個人網站。
在項目中,咱們須要把src
目錄下的html文件進行打包,打包到dist
目錄下,這裏我以單頁面爲例。在src
目錄下,建立index.html
文件
須要安裝html-webpack-plugin
插件
npm install --save-dev html-webpack-plugin
在webpack.config.js
中引入安裝的插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path'); module.exports = { //入口文件的配置項 entry: { hello: './src/helloworld.js' }, //出口文件的配置項 output: { path: path.resolve(__dirname, 'dist'), filename: '[name].js' }, //模塊,loader都是在這裏面配置 module: {}, //插件 plugins: [ new HtmlWebpackPlugin({ minify: { //移除html中的引號 removeAttributeQuotes: true, //去掉html文件中的回車和空格 collapseWhitespace: true }, hash: true, template: './src/index.html' }) ], devServer: { //設置目錄結構 contentBase: path.resolve(__dirname, 'dist'), //服務器的IP地址 host: '127.0.0.1', //服務端壓縮是否開啓 compress: true, //服務端口號 port: 8081 } };
注意:全部的plugins(插件)都須要安裝並在webpack.config.js文件中引入,而後才能使用。
項目中,css文件須要進行打包,在入口js文件中經過import
引入css文件
import css from './css/index.css'
css文件打包須要依賴兩個包
style-loader:用來處理css文件中的url()等,url掛在到js中
css-loader:用來將css插入到頁面的style標籤 安裝style-loader:npm
安裝兩個依賴包:
install --save-dev style-loader css-loader
在webpack.config.js
文件中進行配置
module: { rules: [ { test: /\.css$/, use: [ { loader: 'style-loader' },{ loader: 'css-loader' } ] } }
注意:這兩個包的引入是有前後順序的,必定要縣引入
style-loader
而後再引入css-loader
,由於兩個文件有依賴關係。
執行命令進行打包:
npm run build
注意: 這時css文件中的代碼會被打包到js裏面
項目中大多數時候咱們須要把css文件單獨分離出來,而不是打包到js文件中,這時就須要依賴插件extract-text-webpack-plugin
,安裝插件
npm install --save-dev extract-text-webpack-plugin
在webpack.config.js
文件中引入插件
const ExtractTextPlugin = require("extract-text-webpack-plugin");
module: { rules: [ { test: /\.css$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: ["css-loader"] }) } ] }
在plugins
中引入
plugins: [ new HtmlWebpackPlugin({ minify: { removeAttributeQuotes: true, collapseWhitespace: true }, hash: true, template: './src/index.html' }), new ExtractTextPlugin("css/index.css") ]
css文件會分離出來,但若是css中引用的圖片不是base64格式而是獨立的圖片文件, 這時候就會出現路徑問題致使找不到圖片地址,須要在output
配置publicPath
來解決,其中IP地址和端口號須要根據本身項目的實際狀況來配置
output: { path: path.resolve(__dirname, 'dist'), filename: '[name].js', publicPath: 'http://127.0.0.1:8081/' }
項目上線後,js文件一般都是須要進行壓縮的,這樣能夠減少文件體積加快加載速度,固然webpack
中已經自帶了uglifyjs-webpack-plugin
插件來實現js代碼壓縮功能。
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
在webpack.config.js
文件中的plugins
中增長
plugins: [ new HtmlWebpackPlugin({ minify: { removeAttributeQuotes: true, collapseWhitespace: true }, hash: true, template: './src/index.html' }), new ExtractTextPlugin("css/index.css"), new UglifyJSPlugin() ]
注意:使用
npm run build
命令能夠打包成功,js文件也能夠進行壓縮,可是使用npm run server
開啓dev server
是就會報錯,緣由是當前還處於開發模式中,正常狀況下開發模式是不須要進行js文件壓縮的,因此會報錯。等到真正上線在生產模式下也不可能會使用der server
的。
圖片打包分爲兩節介紹,由於在網頁開發中圖片引用的方式主要是兩種,一種是在css文件
中做爲背景圖片background-image: url(xx.jpg)
,另外一種是在html文件中
使用標籤引入<img src="xx.jpg"/>
須要依賴兩個loader
,分別是file-loader
和 url-loader
,固然也必定是須要先安裝後使用了
npm install --save-dev file-loader url-loader
在module
中增長對圖片的規則
{ // 匹配圖片文件後 綴名稱。 test: /\.(png|jpg|gif)/, // 指定使用的loader和配置參數 use: [{ loader: 'url-loader', options: { // 把小於5000B的文件打成Base64的格式寫入JS,大於這個大小的圖片文件會生成單獨的圖片文件,這個大小具體多少看實際項目要求,單位爲B limit: 50000, // 圖片輸出到dist文件夾中的images文件夾中 outputPath: 'images/' } }] }
注意:在
loader
中咱們只配置了url-loader
而沒有配置file-loader
,緣由是url-loader
封裝了file-loader
。當文件大於limit
中限制大小須要生成圖片文件時,url-loader
會調用file-loader
進行處理,參數也會直接傳給file-loader
須要依賴於html-withimg-loader
npm install html-withimg-loader --save-dev
在module
中增長對html
文件的規則
{ test: /\.(html|htm)$/i, use: ['html-withimg-loader'] }
什麼是SASS?CSS 預處理器定義了一種新的語言,其基本思想是,用一 種專門的編程語言,爲 CSS 增長了一些編程的特性,將 CSS 做爲目標生成文件,而後開發者就只要使用這種語言 進行編碼工做。
通俗的說,「CSS 預處理器用一種專門的編程語言,進行 Web 頁面樣式設計,而後再編譯成正常的 CSS 文件,以供 項目使用。CSS 預處理器爲 CSS 增長一些編程的特性,無 需考慮瀏覽器的兼容性問題」,例如你能夠在 CSS 中使用
變量、簡單的邏輯程序、函數等等在編程語言中的一些基 本特性,可讓你的 CSS 更加簡潔、適應性更強、可讀性
更佳,更易於代碼的維護等諸多好處。
在開發過程當中,使用擴展名爲.scss
的文件來編寫css樣式
,但該文件並不能直接被瀏覽器解析,因此就須要編譯爲.css
的文件,通常是使用sass
命令來進行編譯,在webpack
中使用loader
來編譯該文件。
安裝loader
npm install --save-dev node-sass sass-loader
在js中引入編寫好的.scss
文件
import sass from './css/common.scss';
在module
中增長對scss
文件的規則
{ test: /\.scss$/, // use: ['style-loader', 'css-loader', 'sass-loader'] use: ExtractTextPlugin.extract({ fallback: "style-loader", use: ["css-loader", "sass-loader"] }) }
注意:CSS預處理不僅有SASS,我這裏只是以SASS爲例來演示
webpack
對於css預處理的打包支持
咱們常常會爲css3的屬性前綴而苦惱,-webkit-
,-moz-
,-ms-
,-o-
,通常都是經過http://www.caniuse.com來查詢,如今有了webpack
自動加前綴的功能媽媽就不再用擔憂個人學習啦~~
npm install postcss-loader autoprefixer --save-dev
在項目的根目錄下建立文件postcss.config.js
module.exports = { plugins: [ require('autoprefixer') ] }
在module
中修改對於css文件的規則
{ test: /\.css$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: [{ loader: "css-loader", options: { importLoader: 1 } }, "postcss-loader"] }) }
打包之後發現css3
屬性的前綴就能夠自動加上啦啦啦~~
如今愈來愈多的項目已經採用ES6
甚至ES7
ES8
的新特性來編寫代碼了,但有些語法並不能直接被瀏覽器識別,這就須要轉化成瀏覽器能夠直接識別的代碼,就須要用到babel
npm install --save-dev babel-core babel-loader babel-preset-env babel-preset-react
在module
中修改對於js
jsx
文件的規則
{ test: /\.(js|jsx)$/, use: { loader: 'babel-loader', options: { presets: ['env', 'react'] } } }
打包成功會發現新語法已經轉化爲ES5
的語法了
有的時候咱們須要在文件中直接打包進去一些註釋信息,webpack
自帶的BannerPlugin
插件就能夠幫咱們實現這個功能。在plugins
中增長
new webpack.BannerPlugin('成哥全部,翻版必究!'),
項目中咱們常常須要用到第三方類庫,好比jquery
vuejs
等,這就須要咱們進行相應的配置。
安裝第三方類庫,這裏以jquery
vuejs
爲例
npm install jquery vue --save
在plugins
中增長
new webpack.optimize.CommonsChunkPlugin({ name: ['jquery', 'vue'], filename: 'assets/js/[name].js', minChunks: 2 })
webpack
的入門指南算是總結完了,其實webpack
的強大之處還遠不止於此,我只是在本身實踐中總結下來一些經常使用的功能,但願能夠對入門webpack
的小夥伴有所幫助。