手把手教webpack,力求作通俗易懂的前端工具教程

瀏覽器使用es6代碼

2.1運行第一章中的es6代碼

新創建文件夾chapter2 新創建網頁index.html內容以下javascript

<script>
(a)=>{alert(1)}
</script>

打開index.html查看瀏覽器控制檯F12:css

Uncaught SyntaxError: Unexpected token =>

瀏覽器不支持ES6腳本語言箭頭符
咱們須要能識別ES6的軟件
幫助咱們把es6代碼轉換成es5瀏覽器能識別的代碼html

安裝第3方軟件幫助咱們使用es6

2.2 安裝node.js

第3方軟件做爲node.js模塊軟件包
想使用這些軟件必須先安裝node.js前端

2.2 安裝npm

新版的node.js已經集成NPM
咱們能夠經過npm下載管理全部的軟件包
你們能夠在windows控制檯窗口輸入npm -v查看當前版本vue

2.3 切換到chapter2目錄 在控制檯輸入npm.init

做用:把當前項目配置成軟件包
而且和其餘軟件包交互依賴關係
一直點下一步便可
node.js會在當前項目生成packgae.json
該文件咱們只須要了解如下字段配置
//做爲軟件包入口,當本項目做爲軟件包調用時java

"main": "index.js"

//本項目依賴的其餘軟件包node

"description":..`

//使用-dev指令 下載的軟件包依賴react

devDependencies:..

2.4 經過npm安裝babel命令行軟件包解析es6語法

//把babale-cli安裝到node全局路徑上jquery

npm install -g babel-cli

//使用--save自動配packgae.json依賴關係
//而且把babel命令行程序安裝到項目路徑webpack

npm install --save babel-preset-es2015`

這時候你會發現你當前項目路徑上出現了1個文件夾node_modules
打開看看哇塞好多文件啊這就是babel用來解析es6的全部文件
此刻說明babel已經安裝好了
咱們在項目路徑下創建1.js 寫入如下代碼

(a)=>{alert(1)}

點擊windows開始運行輸入cmd啓動控制檯
cd命令切換到當前項目路徑運行:

babel 1.js --presets es2015

控制檯會顯示:

"use strict";
(function (a) {
alert(1);
});

咱們獲得了能夠在瀏覽器上使用的es5代碼
把控制檯的代碼寫到1.js中
修改index.html

<script type='text/javascript' src='./1.js'></script>

若是感受麻煩能夠把控制檯的代碼寫入本地硬盤文件中

babel 1.js --presets es2015 -o 2.js

修改index.html

<script type='text/javascript' src='./2.js'></script>

瀏覽器再也不報錯

2.5 babel轉換帶來新的問題

babel也安裝了,es6也能被babel解析成es5了
一切都那麼OK
真的是這樣麼?咱們修改1.js

import name from './3.js'   
(a)=>{alert(name)}

通過第一章的學習上面的代碼的意識是
咱們須要使用3.js中的被默認導出的變量name
當前目錄下創建3.js

name="李雷"   
export default name

運行babel 編譯1.js輸入到2.js中

'use strict';
var _ = require('./3.js');
var _2 = _interopRequireDefault(_);
function _interopRequireDefault(obj)
{ return obj && obj.__esModule ? obj : { default: obj }; }
(function (a) {
alert(1);
});

打開index.html點擊F12查看控制檯

Uncaught ReferenceError: require is not defined

又出錯了!沒辦法解析require

好麻煩啊不想繼續看了!前端搞這麼複雜

堅持下 不用記下來
能看懂配置文件就能夠

咱們須要能解析require命令的軟件!

2.6 require的效果合併js文件

想象若是1.js是以下這樣的就行了

name="李雷"  //來自3.js中的變量定義
(a)=>{alert(name)}  //原來1.js中代碼定義

沒錯咱們須要把1.js和3.js這兩個文件合併到一塊兒
這樣咱們就能在1.js中使用name(來自3.js中的name)變量了

2.7 在當前項目(chapter2文件夾)安裝webpack,解析require指令

npm install webpack --save

點開package.json看看

"dependencies": {
     "babel-preset-es2015": "^6.22.0",
      "webpack": "^2.2.1"
      }

說明目前項目webpack引用成功

2.8 配置webpack

在當前項目下創建 webpack.config.js

var webpack =require('webpack');
     var path =require('path')
     module.exports = {
     entry: {
     //要打包的入口文件  
     //若是不寫main默認會生成main文件
     main:'./1.js',
     //顯示指定了name='index'
     //若是取消了註釋,entry包括2個屬性 main和index會分別把1.js和2.js打包2個文件
    //index:'2.js',
     },
    output: {
    //打包文件之後生成的新的文件的地址
     path: path.resolve(__dirname,'build'),
    //打包文件之後生成的新的文件名稱
    filename:'[name].bundle.js',
    //靜態資源文件好比圖片等被打包之後的資源路徑
    publicPath:'http://127.0.0.1'
    },
    module: {
    loaders: []
    },
    plugins:{}
    }

2.9 運行webpack

在windows命令行裏切換到當前項目輸入webpack
查看當前目錄出現了build文件夾
在build文件夾中創建index.html

<script type='text/javascript' src='./main.bundle.js'></script>

裏面看到webpack新生成的index.bundle.js
點擊index.html
點擊F12查看控制檯發現。。竟然報錯了

Uncaught SyntaxError: Unexpected reserved word

原來不識別箭頭符號
咱們之前安裝的babel-cli是控制命令行程序
須要用戶手動進入控制檯輸入babel命令才能觸發es6轉換
如何讓webpack也能使用babel指令?

2.10 讓webpack使用babel,安裝webpack版本babel插件

npm install babel-loader    
npm install babel-preset-es2015 --save    
npm install babel-core --save

修改webpack.conf.js配置插件

var webpack =require('webpack');
var path =require('path')
module.exports = {
 entry: {
 main:'./1.js'
      },
 output: {
  //打包後的文件路徑
  path: path.resolve(__dirname,'build'),
  //打包後的文件名字
  filename:'[name].bundle.js',
  //使用import導入靜態資源好比jpg
  //會自動添加前綴
  // import './1.jpg'
  //http://127.0.0.1/1.jpg
  publicPath:'http://127.0.0.1/'
     },
 module: {
   loaders: [
              {
          //匹配該路徑下的全部文件使用對應的加載器
                  test: path.join(__dirname, './'),
         //使用babel插件  
          loader: 'babel-loader' ,
          query: {
         //使用es6轉換
            presets: ['es2015']
         }
   }
   ]
   },
   plugins:{}
   }

命令行切換到項目路徑使用webpack命令
會提示生成 main.bundle.js
頁面引入 main.bundle.js
看看效果

還有其餘的webpack相關loader插件麼?

2.11 css-loader

給input添加css樣式
項目目錄新建文件loader.js文件 咱們準備操做dom

var input = document.createElement("input");
input.setAttribute("class",'input');
var loader  =document.getElementById('loader')
loader.appendChild(input)

項目目錄 創建input.css

.input{width:1000px}

項目目錄下切換到build文件夾 修改index.html

<div id='loader'>
</div>
<script type="text/javascript" src="./main.bundle.js"></script>

考慮本頁面index.html如何要引入input.css
方式1:本頁面引入input.css文件
手動複製input.css文件到build文件夾下
優勢:方便 可視化
缺點1:使用css文件須要在html頁面導入 浪費網絡請求
缺點2:build文件夾下須要有input.css,但是我不想把css文件放這裏
方式2:把css壓縮到js文件中
優勢1:把css文件 把css合併到index.bundle.js中 節省流量
優勢2:build目錄不須要再手動複製input.css文件
缺點:css被壓縮到js文件中 再也不可視化
採用方式2

npm install css-loader --save

修改webpack.conf.js

loaders: [
{
  test: path.join(__dirname, './'),   
  loader: 'babel-loader' ,
  query: {
  presets: ['es2015']
         }
},
{
//只要被編輯的js文件,使用了import或者require指令發現".css"結尾  
//都會執行對應的loader   
  test: /\.css$/,
>     //添加對應的loader 要寫上style-loader和css-loader哦
//後面的importLoaders=1表示執行順序 用數字大小判斷前後執行
loader: 'style-loader!css-loader?importLoaders=1'
 },

此時的webpack.conf.js的配置以下

var webpack =require('webpack');
var path =require('path')
module.exports = {
     entry: {
     main:'./loader.js'
      },
     output: {
     path: path.resolve(__dirname,'build'),
     filename:'[name].bundle.js',
     publicPath:'http://127.0.0.1/'
     },
     module: {
     loaders: [
     {
     test: path.join(__dirname, './'),
     loader: 'babel-loader' ,
     query: {
     presets: ['es2015']
     }
     },
     {
     test: /\.css$/,
     loader: 'style-loader!css-loader?importLoaders=1'
          },
     ]
     },
     plugins: []
     }

如何把css打包到js文件中

//使用導入指令 webpack能夠自動處理該js和css合併
import './input.css';
var input = document.createElement("input");
var loader  =document.getElementById('loader')
input.setAttribute("class",'input');
loader.appendChild(input)

打包:進入項目目錄運行webpack loader.js
導入編譯後的mian.bundle.js
點開index.html
看看效果

2.12 url-loader

上面的css-loader能夠把css文件合併到js文件中
如何把圖片打包到js文件中呢?
採用url-loader

npm install url-loader --save

修改webpack.conf.js 添加對應的loader``

{
test: /\.jpg$/,
//注意該項loader必須加[]不然會報錯
//變量介紹
//[ext]:匹配到的文件擴展名 好比jpg等等
//[path]:使用import指令導入的圖片路徑
//好比import img1 from './images/1.jpg'
//那麼[path]='images'
//[name]='文件名稱'
//[hash]='md5編碼'
//name:使用該loader生成的文件名字
//limit:指定字節大小 小於這些字節的圖片被強制轉換成base64
loader: ['url-loader?limit=10000&name=[path][name].[ext]?[hash]'],
},

問題1:使用如下loader會如何處理圖片

`loader: ['url-loader?limit=10000&name=[path][name].[ext]?[hash]']`

問題2:小明配置好了loader開始在代碼中使用

import './input.css'
var input = document.createElement("input");
input.setAttribute("class",'input');
var loader  =document.getElementById('loader')
loader.appendChild(input)
var img=document.createElement("img");
//代碼中使用圖片url-loader處理該圖片
img.src="./images/1.jpg";
loader.appendChild(img)

請問小明上述操做是否正確?可否正確使用url-loader處理圖片

2.13 file-loader

npm install file-loader --save

file-loader用於把文本文件或者圖像合併到js文件中作處理
其實用處不大,文本自己就能夠定義在js文件中,若是要處理圖像可使用url-loader

2.14 image-webpack-loader

npm installimage-webpack-loader --save

用於壓縮圖片,圖片優化等
配置信息以下

{
//該表達式使用多個loader  
test: /\.(png|jpe?g|eot|svg|ttf|woff2?)$/,  
loader:  ['file-loader?digest=hex&name=[hash].[ext]',
 'image-webpack-loader?bypassOnDebug&optimizationLevel=7&interlaced=false'
]},

loader配置優化URL參數

2.15 中的loader配置的URL信息太長,咱們優化下

使用query表示查詢參數

{
//該表達式使用多個loader  
test: /\.(png|jpe?g|eot|svg|ttf|woff2?)$/,  
loaders:[
{loader:file-loader,
  query:{
   digest:hex,
   name:[hash].[ext]
       }//end query
       },//end file-loader
{loader: 'image-webpack-loader'
  query: {
    progressive: true,
    optimizationLevel: 7,
    interlaced: false,
    pngquant: {
      quality: '65-90',
        speed: 4
      }
 }////end img-loader

]},

使用第3方類庫

2.16 使用jquery

npm install jquery --save

新創建jquery.js
代碼以下

import './input.css';
import $ from 'jquery';
var input = $("<input class='input' />");
var loader  =$('#loader')
console.log($)
loader.append(input)
loader.append(input)

配置webpack.conf.js入口文件爲jquery.js
命令行運行webpack jquery.js 啓動編譯
引入編譯文件 點開index.html

問題3:請問會上述代碼會顯示幾個input? 本問題和本章無關,你們看到這裏也很累了~作下測試看看 ?
問題4: 控制檯打印出來了$ 是jquery,那麼引用成功了麼?

2.17 使用基於jquery的插件

項目的build文件夾下新建jquery-plus.js

//該插件:jquery對象調用message()會彈出提示
 (function($){
 $.extend({
 message:function(message){
 alert(message);
 }
 });
 })(jQuery);

修改index.html

<div id='loader'>
 </div>
 <script type="text/javascript" src='./main.bundle.js?v=4'></script>
 <script src="./jquery-plus.js"></script>
 修改jquery.js
 import './input.css';  
 import $ from 'jquery';  
 var input = $("<input class='input' />");  
 var loader  =$('#loader')  
 console.log($)  
 loader.append(input)  
 loader.append(input)  
 $.message('1');  
 編譯jquery.js,點開index.html

控制檯成功打印了$是jquery
可是調用message的時候提示

會提示`Uncaught TypeError: undefined is not a function`   
 Uncaught ReferenceError: jQuery is not defined`   

 請思考問題4

2.18 調用jquery插件出錯緣由

上面定義的jquery插件須要依賴window.jquery ,window.$
咱們使用import指令導出的jquery或者$只再當前js文件做用域內生效
(在每一個js文件內生成了閉包 外部其餘文件沒辦法訪問到裏面的內容)
致使jquery-plus.js中沒辦法獲取到$
咱們須要把import導入的jquery賦值給windows
項目路徑新建文件jquery-core.js
該js文件用於給windows相關的jquery賦值

import $ from 'jquery'
 window.$ = $
 window.jQuery = $
 /export指令請參考第一章內容 使用es6編寫代碼
 export default $

把jquery-plus.js複製到項目目錄(原來在打包的build目錄) 內容

function($){
 $.extend({
 message:function(message){
 alert(message);
 }
 });
 })(jQuery);

修改項目路徑下的jquery.js

import './input.css';
 import $ from './jquery-core.js';
 import  plus from './jquery-plus.js'
 var input = $("<input class='input' />");
 var loader  =$('#loader')
 console.log($)
 loader.append(input)
 loader.append(input)
 $.message(1)
 編譯打包jquery.js
 webpack jquery.js
 index.html引入打包後的js文件
 點擊index.html看看效果

上面的使用jquery方案必須熟練

之後在react或者vue或者相似的框架使用webpack打包的項目中  
 若是想使用相似jquery這樣的第3方庫 須要這樣添加

2.19 使用webPack動態熱處理

上面的全部教程例子都是須要運行如下命令行

webpack 要打包的js文件    
 而後在手動點擊index.html   
 很麻煩,webpack幫咱們提供了方便的操做

安裝,配置webpack-dev-server

npm install webpack-dev-server

配置webpack.conf.js
在module.exports中添加新的屬性

devServer:{
 //history API,若是設置爲true,全部的跳轉將指向index.html  
 //開發單頁應用的時候須要配置  
 //若是不配置:  
 //訪問127.0.0.1/gift  
 //會打開WEB服務器上的gift資源路徑下的index.html  
 //在單頁應用中 gift表示模塊路徑
 //即訪問127.0.0.1/gift   
 //web服務器會把請求轉發到127.0.0.1/index.html上
 //等價於訪問127.0.0.1/index.html#gift
 //咱們須要在服務器配置url重寫,即開啓apache .htaccess
 //配置了此項,咱們無需配置服務端,webPack會自動幫咱們配置
 historyApiFallback:true,
 //定義web服務器加載首頁的路徑,去這個路徑下加載index.html
 contentBase:'./build',
 //自動刷新機制 inline,推薦使用inline模式
 //開啓之後contentBase下的index.html中必需要引入
 //<script  src="http://localhost:9090/webpack-dev-server.js"></script>    
 //利用webSocket和webpack-dev-server通訊  
 //webpack-dev-server後端文件變化 直接推送到瀏覽器刷新頁面  
 //開啓inline訪問路徑是127.0.0.1:9090/index.html
 //若是關閉 inline:false  
 //刷新模式改變成iframe模式
 //訪問路徑http://localhost:9090/webpack-dev-server/index.html
 inline:true,
 port:9090 //端口你能夠自定義
 },
 修改plugins
 plugins: [
 new webpack.HotModuleReplacementPlugin(),
 new webpack.NoEmitOnErrorsPlugin(),
 ]

此時webPack.conf.js配置以下

var webpack =require('webpack');
 var path =require('path')
 module.exports = {
 devServer:{
 //history API,若是設置爲true,全部的跳轉將指向index.html  
 //開發單頁應用的時候須要配置  
 //若是不配置:  
 /訪問127.0.0.1/gift  
 //會打開WEB服務器上的gift資源路徑下的index.html  
 //在單頁應用中 gift表示模塊路徑
 //即訪問127.0.0.1/gift   
 //等價於訪問127.0.0.1/index.html#gift
 //咱們須要在服務器配置url重寫,即開啓apache .htaccess
 //配置了此項,咱們無需配置服務端,webPack會自動幫咱們配置
 historyApiFallback:true,
 //定義web服務器加載首頁的路徑,去這個路徑下加載index.html
 contentBase:'./build',
 //自動刷新機制 inline
 //利用webSocket和webpack-dev-server通訊  
 //webpack-dev-server後端文件變化 直接推送到瀏覽器刷新頁面  
 //開啓inline訪問路徑是127.0.0.1:9090/index.html
 //若是關閉 inline:false  
 //刷新模式改變成iframe模式
 //訪問路徑http://localhost:9090/webpack-dev-server/index.html
 inline:true,
 port:9090 //端口你能夠自定義
 },
 entry: {
 main:'./jquery.js'
 },
 output: {
 path: path.resolve(__dirname,'build'),
 filename:'[name].bundle.js',
 publicPath:'http://127.0.0.1/'
 },
 module: {
 loaders: [
 {
 test: path.join(__dirname, './'),
 loader: 'babel-loader' ,
 query: {
 presets: ['es2015']
 }
 },
 {
 test: /\.css$/,
 loader: 'style-loader!css-loader?importLoaders=1'
 },
 {
 test: /\.jpg$/,
 loader: ['url-loader?limit=10000&name=[path][name].[ext]?[hash]'],
 },
 ]
 },
 plugins: [
 new webpack.HotModuleReplacementPlugin(),
  new webpack.NoEmitOnErrorsPlugin(),
 ]
 }

修改項目下build文件夾index.html

<script src="http://localhost:9090/webpack-dev-server.js"></script>
 <script>
 //用於webSocket推送刷新頁面
 if(module.hot) { module.hot.accept() }
 </script>
 <div id='loader'>
 </div>
 <script type="text/javascript" src="./main.bundle.js"></script>

命令行啓動webpack-dev-server

修改package.json 添加如下屬性 "scripts": { "start1": "webpack-dev-server --inline --watch" }, 在命令行輸入npm run start1 訪問127.0.0.1:9090 隨意修改jquery.js看看熱更新效果

相關文章
相關標籤/搜索