webpack學習

webpack學習

一、初識webpack

? 我們已經(jīng)知道了模塊化開發(fā)是非常重要和必要的了巾腕,而且也了解了一些前端模塊化的方案:AMD、CMD混移、CommonJS祠墅、ES6.

? 在ES6之前,要是想使用上面那些模塊化開發(fā)的方案歌径,那就必須得依靠一些對這些方案有底層支撐的一些工具,因為ES5的語法中根本就沒這些東西亲茅,我們需要有東西來對這些方案的語法進行解析回铛。而且,在模塊化開發(fā)完成之后還要進行一個整合和打包克锣,處理模塊間的依賴關(guān)系茵肃。一個項目中,有多個模塊進行導出和導入袭祟,關(guān)系會變得非常復雜验残,所以需要有工具幫我們處理一下這些依賴關(guān)系。

webpack處理模塊間依賴關(guān)系什么意思巾乳?

? 就是你只需要將一個入口的js文件進行打包您没,它會自動幫你找是否有依賴其它包,一層一層的處理下去然后打包成一個瀏覽器認識的js文件胆绊。

a.什么是打包氨鹏?

1.打包就是將各種資源模塊進行打包合并成一個或者多個包(Bundle)

2.對資源進行處理,比如說壓縮圖片压状,預處理Sass,less,將ES6語法轉(zhuǎn)成ES5的語法仆抵,將TypeScript轉(zhuǎn)成javascript等等

b.打包的工具有很多,像是grunt/gulp种冬,它們有什么不同镣丑?

1.grunt/gulp的核心是Task,通過配置一系列的task,定義task要處理的事務娱两,比如說壓縮圖片莺匠,預處理Sass,less,將ES6語法轉(zhuǎn)成ES5的語法,將TypeScript轉(zhuǎn)成javascript等等谷婆,然后讓grunt/gulp來依次執(zhí)行這些task慨蛙,讓整個流程自動化辽聊,所以grunt/gulp也被稱為前端自動化任務管理工具它們強調(diào)的是前端流程的自動化期贫,模塊化不是它們的核心跟匆,也是通過配置一些東西,把模塊化作為一個task去處理而已通砍,而且會很復雜玛臂。

2.webpack更加強調(diào)模塊化開發(fā)的管理,官網(wǎng)解釋webpack就是一個現(xiàn)代的JavaScript應用的靜態(tài)模塊打包工具封孙,而壓縮圖片迹冤,預處理Sass,less,將ES6語法轉(zhuǎn)成ES5的語法,將TypeScript轉(zhuǎn)成javascript等等的功能只不過是它的附加功能虎忌。

二泡徙、安裝webpack

webpack對于模塊化開發(fā)很重要,所以就先安裝來使用吧

webpack要想運行需要依賴Node.js環(huán)境膜蠢。Node.js為了正常運行很多代碼堪藐,需要依賴各種包,所以它自帶了一個軟件包管理工具npm挑围。所以通過npm來安裝webpack礁竞。

webpack有兩種安裝方式

? 1.全局安裝,version是指定的版本 杉辙,-g表示全局安裝global

npm install webpack@version -g

? 2.局部安裝

cd 想要安裝的目錄
npm install webpack@version --save-dev

為什么全局安裝后模捂,還需要局部安裝呢?

  1. 在終端執(zhí)行webpack命令時蜘矢,使用的是全局安裝的webpack
  2. 當在package.json中定義了scripts時狂男,其中包含的webpack命令首先是找局部的webpack,找不到才用全局的硼端。

三并淋、webpack起步

現(xiàn)在可以進行模塊化開發(fā)了

mathUtil.js

function add(num1,num2) {
  return num1 + num2;
}
function mul(num1,num2) {
  return num1 * num2;
}
//CommonJS
module.exports = {
  add,mul
};

main.js

//CommonJS
const {add,mul} = require("./mathUtil.js");
console.log("Hello webpack");
console.log(add(10, 20));
console.log(mul(10, 20));
//ES6
import * as author from "./author.js";

console.log(author.name);
console.log(author.age);
console.log(author.height);

author.js

//ES6
const name = "WaiGo";
const age = 20;
const height = 1.80;
export {
  name,age,height
}

通過在終端輸入webpack指令進行打包,因為瀏覽器本身肯定不認識CommonJS

webpack main.js的地址 想要放入打包后的Js文件的地址

你會發(fā)現(xiàn)這里只是對main.js進行了打包珍昨,沒有管mathUtil.js和author.js县耽,webpack會自動找main.js中依賴了哪些模塊然后去進行一些處理的,這就是處理依賴關(guān)系镣典。

然后將打包好的js文件進行引入使用就可以了兔毙。

四、webpack.config.js配置和package.json配置

? 1.上面的webpack指令是不是挺麻煩的兄春,每次都要寫將哪里的入口文件打包到哪個出口文件澎剥,挺麻煩的,所以下面就通過webpack.config.js的配置文件實現(xiàn)我們只需要寫一個webpack指令赶舆,它就知道是把main.js給打包到bundle.js中哑姚。

module.exports = {
  //需要打包的文件祭饭,入口JS文件
  entry: "./src/main.js",
  //1.入口文件可以直接寫當前路徑的main.js文件,直接寫相對路徑就可以叙量,
  // 就是相對于webpack.config.js的路徑
  //2.output是出口倡蝙,這需要一個對象
  //包括這個輸出文件的地址path和文件名filename
  //dist是distribute發(fā)布的意思
  output: {
    path:"./dist",
    filename:"bundle.js"
  }
};

注意這個path一定要是一個絕對路徑,寫相對路徑會報錯

Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.

  • configuration.output.path: The provided value "./dist" is not an absolute path!

錯誤信息說绞佩,這是無效的配置對象寺鸥,webpack在初始化的時候使用配置對象但是并沒有符合API schema的限制,因為"./dist"不是一個絕對路徑

const path = require("path");
module.exports = {
  //需要打包的文件品山,入口JS文件
  entry: "./src/main.js",
  //1.入口文件可以直接寫當前路徑的main.js文件胆建,直接寫相對路徑就可以,
  // 就是相對于webpack.config.js的路徑
  //2.output是出口肘交,這需要一個對象
  //包括這個輸出文件的地址path和文件名filename
  //dist是distribute發(fā)布的意思
  //3.path是一個絕對路徑笆载,那么肯定不要自己把它給寫死了,應該是動態(tài)獲取的
  //Node里有個叫做path的模塊酸些,path就能拿到當前webpack.config.js的路徑
  //所以要先下載這個依賴宰译。
  // 1.想要使用Node里面的模塊,就必須先有個package.json文件魄懂,它是Node對
  //  包進行管理需要用到的文件,先通過npm init來創(chuàng)建這個json文件
  // 2.如果這個json文件中有一些依賴的話闯第,需要通過npm install來下載這些依賴
  output: {
    //__dirname(注意注意:這個dirname前面是有兩個下劃線的)是Node上下文的一個
    // 全局變量市栗,保存著webpack.config.js這個文件的絕對路徑,path模塊中有個
    // resolve方法可以進行路徑拼接咳短,就可以拼接出輸出絕對路徑了
    path:path.resolve(__dirname,"dist"),
    filename:"bundle.js"
  }
};

五填帽、局部安裝webpack

我們之前使用的webpack是全局的webpack,可能我們的項目使用的webpack的版本和全局的版本不一致咙好,所以就要有個項目本地的webpack篡腌,然后把webpack指令映射到package.json中的scripts腳本中,這樣在使用npm run的指令的時候使用的就是項目本地的webpack而不是全局的webpack了勾效。

通過下面的指令安裝局部webpack

cd 到需要安裝的目錄
npm install webpack@version --save-dev

--save-dev表示是開發(fā)時依賴

npm官方鏡像安裝非常慢嘹悼,但是使用淘寶的cnpm就挺快的

npm install -g cnpm --registry=https://registry.npm.taobao.org

這樣就可以通過cnpm來替換npm下載了

六、配置package.json文件

將webpack指令映射成npm run build指令层宫,這樣才能使用本地的webpack而不是全局的webpack杨伙。不然就得寫這么一長串指令了

node_modules/.bin/webpack

就這樣配置映射

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack"http://這就可以使用npm run build指令打包了
  },

七、loader

webpack能夠把css,TypeScript等等的東西也當成一個模塊進行處理萌腿,這樣就不用引入很多文件了限匣,不過原始的webpack指令是沒辦法處理js之外的文件的,所以就需要loader來擴展webpack的功能毁菱。

使用步驟:

? 1.通過npm 安裝需要使用的loader

? 2.在webpack.config.js中的module關(guān)鍵字下進行配置

可以進入webpack官網(wǎng)中找到相應的loader進行學習用法

官網(wǎng)這樣解釋loader

loader 用于對模塊的源代碼進行轉(zhuǎn)換米死。loader 可以使你在 import 或"加載"模塊時預處理文件锌历。因此,loader 類似于其他構(gòu)建工具中“任務(task)”峦筒,并提供了處理前端構(gòu)建步驟的強大方法究西。loader 可以將文件從不同的語言(如 TypeScript)轉(zhuǎn)換為 JavaScript,或?qū)?nèi)聯(lián)圖像轉(zhuǎn)換為 data URL勘天。loader 甚至允許你直接在 JavaScript 模塊中 import CSS文件怔揩!

a.如何將css文件打包

  • style-loader 將模塊的導出作為樣式添加到 DOM 中
  • css-loader 解析 CSS 文件后,使用 import 加載脯丝,并且返回 CSS 代碼

需要這兩個loader,先安裝

cnpm install style-loader --save-dev
cnpm install css-loader --save-dev

在webpack.config.js文件中進行配置

module: {
  rules: [
    {
      test: /\.css$/,
      //1.css-loader只負責css文件加載商膊,不會解析
      //2.style-loader負責將樣式添加到DOM中
      //使用多個loader時,webpack是從*右向左讀*的宠进,
      // 若是沒使用css-loader解析就用style-loader會直接報錯
      //所以順序不能亂
      use: ['style-loader','css-loader' ]
    }
  ]
}

編寫一個css文件并在main.js中導入

//導入css文件
require("./css/normal.css");

這時候使用npm run build就可以打包css了

若是沒有css-loader和style-loader打包css會報錯晕拆,說需要一些合適的loader才能打包。

b.如何打包less文件

打包less材蹬,除了上面的兩個loader之外還要一個less-loader和less(用來轉(zhuǎn)換less成css的工具)

同樣实幕,第一步安裝

cnpm install --save-dev less-loader less

第二步,配置

{
        test: /\.less$/,
        use: [{
          loader: "style-loader" // creates style nodes from JS strings
        }, {
          loader: "css-loader" // translates CSS into CommonJS
        }, {
          loader: "less-loader" // compiles Less to CSS
        }]
      }

把這個加在modul的rules里面就可以了堤器,然后在入口文件中依賴less文件昆庇,然后打包就可以了。

c.如何進行圖片打包

? webpack把圖片也當作了模塊闸溃,而且不需要像引入css文件那樣使用import/require來導入整吆,如果在css中使用了就算是引用了。然后通過url-loader或者file-loader來打包辉川。

若是file-loader打包就會將這個圖片以32位哈希值為文件名拷貝一份放在dist文件夾下表蝙。

若是使用url-loader打包就會將圖片給轉(zhuǎn)換成base64的字符串。

使用url-loader還是file-loader是看的modul.rules里那個url-loader配置的options里的limit的閾值乓旗,大于就使用file-loader府蛇。若是使用file-loader就會在dist中產(chǎn)生一個新的名字的圖片。

所以需要安裝兩個loader,url-loader和file-loader

cd 對應目錄
npm install --save-dev url-loader
npm install --save-dev file-loader

配置一下url-loader就可以進行打包了屿愚,file-loader是不需要特別配置的汇跨,當圖片的大小超過url-loader的閾值后就自動使用file-loader了。

{
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              //當加載的圖片小于limit時渺鹦,會將圖片編譯成base64的字符串形式
              //當加載的圖片大于limit時扰法,就會去使用file-loader來加載
              limit: 8196//文件的大小8kb
            }
          }
        ]
      }

因為使用這個css文件的html文件沒有在dist中,那么它是加載不到這個圖片的毅厚,為了讓html文件能夠加載到這個圖片塞颁,我們需要對webpack.config.js文件里的output添加一個屬性publicPath:'dist/',這樣它在打包所有路徑的時候都會在前面先加一個這個屬性的值。這樣就找得到了。它原來會將圖片相對于dist文件夾的路徑返回放到圖片的地址那里祠锣,但是由于html文件在外面肯定找不到了

output: {
  //__dirname(注意注意:這個dirname前面是有兩個下劃線的)是Node上下文的一個
  // 全局變量酷窥,保存著webpack.config.js這個文件的絕對路徑,path模塊中有個
  // resolve方法可以進行路徑拼接伴网,就可以拼接出輸出絕對路徑了
  path:path.resolve(__dirname,"dist"),
  filename:"bundle.js",
  publicPath:"dist/"
}
打包圖片文件改名

默認使用file-loader產(chǎn)生的圖片名是像這樣子5c6dc1ca2516354142c5612a8021f9e4的一個32位的哈希值蓬推,但是開發(fā)人員可能就不知道是哪一張圖片了,那就需要對這個圖片進行我們想要的改名澡腾。

在url-loader的options里添加一個name屬性沸伏,值為"img/[name].[hash:8].[ext]"

img/:它會在dist中產(chǎn)生一個img文件夾

[name]:是Node中的一個語法,拿到原來圖片的名字

[hash:8]:是Node中的一個語法动分,取8位哈希值毅糟,他會自動運行哈希算法然后返回8位放在這里

[ext]:extension表示擴展名,這是拿到原來的擴展名

{
  test: /\.(png|jpg|gif)$/,
  use: [
    {
      loader: 'url-loader',
      options: {
        //當加載的圖片小于limit時澜公,會將圖片編譯成base64的字符串形式
        //當加載的圖片大于limit時姆另,就會去使用file-loader來加載
        limit: 8196,//文件的大小8kb
        name:"img/[name].[hash:8].[ext]"
      }
    }
  ]
}

d.ES6語法轉(zhuǎn)成ES5的處理

第一步:安裝

npm install --save-dev babel-loader@7 babel-core babel-preset-es2015

第二步:配置

{
  test: /\.js$/,
  exclude: /(node_modules|bower_components)/,
  use: {
    loader: 'babel-loader',
    options: {
      presets: ['es2015']
    }
  }
}

exclude表示這些文件不進行壓縮

官網(wǎng)那種方式需要配置一個babel.rc文件,還沒學到就沒用了坟乾,就先用老師這種方式吧迹辐。

八、引入Vue.js

在webpack中甚侣,vue也是作為一個模塊來看待的明吩,所以是import Vue from "vue";這樣子來使用的,現(xiàn)在需要先把Vue給下載到項目本地殷费。由于Vue不只是開發(fā)時需要依賴贺喝,在運行時也是需要依賴的所以要指定為--save

nam install vue --save

使用

<div id="app">
  {{message}}
</div>
<script src="dist/bundle.js"></script>
import Vue from "vue";
new Vue({
  el:"#app",
  data:{
    message:"Hello Webpack~~~"
  }
});

webpack中的Vue默認使用的是runtime-only的版本,這個是無法解析template的宗兼,需要runtime-complier版本,所以就報了下面這個錯誤氮采。這里老師沒仔細說這兩個版本的區(qū)別殷绍,到后面再補充。這里修改一下webpack的配置就可以使用了鹊漠。

bundle.js:1346 [Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.

//在module.exports = {}中定義一個resolve
resolve:{
  //別名
  alias:{
    //在import的時候會去這個文件夾中找
    'vue$':"vue/dist/vue.esm.js"
  }
}

九主到、el和template的區(qū)別

在之前學習Vue的過程中我們寫的代碼都是直接對vue實例對象掛載的那個div進行操作,都是在以后的開發(fā)中躯概,我們是不希望手動的頻繁去修改html文件中的東西的登钥。就是讓<div id="app"></div>這個掛載到vue實例對象中的DOM元素就這樣為空,但是我們又需要在在里面顯示東西娶靡,那應該怎么處理呢牧牢?

這就提到template屬性了,在vue實例中若是既定義了el屬性,也定義了template屬性塔鳍,那么在運行的時候template中的元素會將el掛載的那個元素完全給替換掉的伯铣。

new Vue({
  el:"#app",
  template:`
  <div>
    <h2>{{message}}</h2>
    <button @click="btnClick">按鈕</button>
  </div>
  `,
  data:{
    message:"Hello Webpack~~~"
  },
  methods:{
    btnClick() {
      console.log("按鈕點擊了");
    }
  }
});

第一步升級:將template給抽離成一個組件,不然Vue實例中的代碼太多了

import Vue from "vue";
const app = {
  template:`
  <div>
    <h2>{{message}}</h2>
    <button @click="btnClick">按鈕</button>
  </div>
  `,
  data(){
    return {
      message:"Hello Webpack~~~"
    }
  },
  methods:{
    btnClick() {
      console.log("按鈕點擊了");
    }
  }
};
new Vue({
  el:"#app",
  template:`<app/>`,
  components:{
    app
  }
});

第二步升級:把組件對象抽離到一個咱們放這個組件對象的文件中轮纫,這樣就好管理了

export default {
  template:`
  <div>
    <h2>{{message}}</h2>
    <button @click="btnClick">按鈕</button>
  </div>
  `,
  data(){
    return {
      message:"Hello Webpack~~~"
    }
  },
  methods:{
    btnClick() {
      console.log("按鈕點擊了");
    }
  }
}

這樣子使用

import Vue from "vue";
import App from "./vue/app.js";
new Vue({
  el:"#app",
  template:`<App/>`,
  components:{
    App
  }
});

第三步升級:將template腔寡,js代碼分離

創(chuàng)建一個Vue Component文件,就是.vue文件

<!--模板-->
<template>
  <div>
    <h2 class = "title">{{message}}</h2>
    <button @click="btnClick">按鈕</button>
  </div>
</template>
<!--JS-->
<script>
  export default {
    name: "app",
    data(){
      return {
        message:"Hello Webpack~~~"
      }
    },
    methods:{
      btnClick() {
        console.log("按鈕點擊了");
      }
    }
  }
</script>
<!--樣式-->
<style scoped>
  .title{
    color:lightgreen;
  }
</style>

使用一個單獨的組件文件掌唾,代碼看起來是真的清爽啊放前。可是這樣子是打包不了的糯彬,因為webpack原先不能處理.vue文件凭语,所以要下載相應的loader

cnpm install --save-dev vue-loader vue-template-compiler

webpack.config.js配置

{
        test: /\.vue$/,
        use:['vue-loader']
      }

這個指令會安裝最新的vue-loader,但是自從vue-loader14點幾的版本之后要想使用這個vue-loader還需要配置一個插件情连。不然就會報錯

Module build failed: Error: Cannot find module '@vue/component-compiler-utils'

若是不想要配置那個插件就得安裝一個小于14的版本叽粹,修改packege.json中的版本號后重新安裝。

"vue-loader": "^13.0.0",

然后重新安裝

cnpm install

現(xiàn)在就可以正常打包運行了却舀。這里說一下虫几,定義組件文件名的時候首字母最好大寫

父子組件例子

子組件

<template>
  <div>
    <h2>我是標題</h2>
    <p>我是共產(chǎn)主義接班人</p>
    <h2>{{message}}</h2>
  </div>
</template>

<script>
  export default {
    name: "Cpn",
    data(){
      return {
        message : "馬克思主義萬歲"
      }
    }
  }
</script>

<style scoped>

</style>

父組件

<!--模板-->
<template>
  <div>
    <h2 class = "title">{{message}}</h2>
    <button @click="btnClick">按鈕</button>
    <Cpn></Cpn>
  </div>
</template>
<!--JS-->
<script>
  import Cpn from "./Cpn.vue";
  export default {
    name: "app",
    data(){
      return {
        message:"Hello Webpack~~~"
      }
    },
    methods:{
      btnClick() {
        console.log("按鈕點擊了");
      }
    },
    components:{
      Cpn
    }
  }
</script>
<!--樣式-->
<style scoped>
  .title{
    color:lightgreen;
  }
</style>

十挽拔、webpack中引用文件的擴展名的問題

如果覺得后綴名麻煩不想寫辆脸,可以在webpack.config.js中的resolve中配置一下extensions:[省略擴展名的文件類型]

resolve:{
  //別名
  alias:{
    //在import的時候會去這個文件夾中找
    'vue$':"vue/dist/vue.esm.js"
  },
  //后綴名
  extensions:['.js','.less','.css','.vue']
}

不過有些時候是不能省略的,比如說在你指定的路徑螃诅,有個app.js和一個app.vue啡氢,那你寫個app,它不知道應該是哪一個术裸。

 import Cpn from "./Cpn";

現(xiàn)在省略掉后綴名就不會報錯了

十一倘是、插件plugin

插件時用于對某個現(xiàn)有的架構(gòu)進行擴展的東西,webpack的插件就是用于對webpack本身的功能進行擴展袭艺。

plugin的使用和loader差不多搀崭,就是通過npm安裝后在webpack.config.js中進行一定的配置后就可以使用了。

  • 添加版權(quán)的Plugin

    在webpack.config.js中配置

    const webpack = require("webpack");
    module.exports = {
        ...
        plugins:[
          new webpack.BannerPlugin('最終版權(quán)歸XXX所有')
          ]
    }
    
  • 打包HTML的plugin

    項目最終發(fā)布的時候只是發(fā)布dist中的內(nèi)容猾编,我們之前的打包都沒有把index.html文件給打包到dist文件夾中瘤睹,這樣dist中的html文件就沒有意義了。所以需要將index.html文件給打包到dist文件夾中答倡,這時需要使用HtmlWebpackPlugin 插件

    功能:

    • 自動生成一個index.html文件轰传,可以指定模板來生成
    • 將打包的js文件,自動添加到生成的這html文件的body中瘪撇。

    安裝:

    cnpm install html-webpack-plugin --save-dev

  • js壓縮的plugin

    在項目發(fā)布之前获茬,肯定需要對js等文件進行壓縮處理港庄,就是去掉空格啊,使用簡單的變量名替換原來的變量名這樣锦茁,就可以將文件的體積縮小攘轩。

    第一步:安裝plugin

    cnpm install uglifyjs-webpack-plugin@1.1.1 --save-dev

    就是丑化js文件

    這里指定版本1.1.1是為了符合webpack3.6.0,不然會報錯码俩,但是現(xiàn)在好像下載不了這個版本了度帮,最新的版本2點幾的又不能適配webpack3.6.0,所以我就先下載了最新的

    cnpm install uglifyjs-webpack-plugin --save-dev

    然后修改package.json中的版本號為1.1.1然后cpnm install去下載1點幾的版本稿存,然后就可以適配了笨篷,應該1.1.1不是一個穩(wěn)定的版本,老師下載的這個版本把橫幅插件的話給刪除了瓣履,但是這個版本沒有輸出率翅,還是打印了一行最終補全歸xxx所有,以后要是出現(xiàn)說版本不匹配的就可以降一下版本試試袖迎。

    第二步:配置webpack.config.js

const uglifyJsPlugin = require("uglifyjs-webpack-plugin");
module.exports = {
...
plugins:[
new uglifyJsPlugin()
]
}


## 十二冕臭、搭建本地服務器

在前面的學習中,你肯定會發(fā)現(xiàn)燕锥,每次對main.js或者是什么進行了修改后想要驗證一下辜贵,都需要npm run build進行再次打包,然后才能驗證代碼是否準確归形。這大大降低了開發(fā)效率托慨,因為每次打包都是要把新的東西寫入硬盤的。所以暇榴,搭建一個本地開發(fā)服務器就非常重要了厚棵,webpack提供了一個可選的服務器。它能時時監(jiān)聽我們打包文件的代碼是否改變蔼紧,若是改變了它會自動編譯改變后的代碼婆硬,然后放在內(nèi)存中而不是直接寫入磁盤仑濒,因為內(nèi)存讀寫速度比磁盤快非常多秕重。

**安裝**:

> npm install --save-dev webpack-dev-server@2.9.1

這個服務器的版本和webpack的版本也有一定的對應關(guān)系,因為現(xiàn)在我的webpack是3.6.0暖眼,就要下載2.9.1

**配置:webpack.config.js**

```javascript
module.exports = {
  ...
  devServer:{
  contentBase:"./dist",
  inline:true//是否實時刷新
}
}

啟動本地開發(fā)服務器的指令是

webpack-dev-server

但是在終端的話要在全局中定位到項目中webpack的地方才能使用這個指令哩至,代碼會是一大串。所以把這個指令映射到package.json中蜜自,就會自動去項目本地找了菩貌,而且只需要敲一段這種指令npm run dev

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack",
    "dev" : "webpack-dev-server"
  },

使用npm run dev就能把本地開發(fā)服務器跑起來了,默認跑在8080端口重荠。然后你可以對main.js中的東西進行一些修改箭阶,你會發(fā)現(xiàn)瀏覽器會自動刷新你修改的內(nèi)容。但是這時候當服務器跑起來之后,你是需要手動去點擊連接才能打開瀏覽器的仇参,你可能想要它自動打開瀏覽器嘹叫,那就在dev指令后面加一個 --open

"dev" : "webpack-dev-server --open"

十三、webpack.config.js配置文件分離

我們之前只有一個webpack.config.js配置文件诈乒,但是在開發(fā)階段我們可能不想要進行一些打包操作罩扇,比如說Js代碼的丑化,這會使得我們代碼難以調(diào)試怕磨。所以現(xiàn)在就把原來的配置文件分成三份喂饥,一份是基本配置,一份是開發(fā)時配置肠鲫,一份是發(fā)布時配置员帮,這樣在不同時間將不同的兩份配置合并成一份配置文件就可以了。開發(fā)時就使用開發(fā)時配置合并基本配置导饲。

基本配置base.config.js

const path = require("path");
const webpack = require("webpack");
const htmlWebpackPlugin = require("html-webpack-plugin");
const uglifyJsPlugin = require("uglifyjs-webpack-plugin");
module.exports = {
  //需要打包的文件捞高,入口JS文件
  entry: "./src/main.js",
  //1.入口文件可以直接寫當前路徑的main.js文件,直接寫相對路徑就可以渣锦,
  // 就是相對于webpack.config.js的路徑
  //2.output是出口硝岗,這需要一個對象
  //包括這個輸出文件的地址path和文件名filename
  //dist是distribute發(fā)布的意思
  //3.path是一個絕對路徑,那么肯定不要自己把它給寫死了泡挺,應該是動態(tài)獲取的
  //Node里有個叫做path的模塊辈讶,path就能拿到當前webpack.config.js的路徑
  //所以要先下載這個依賴。
  // 1.想要使用Node里面的模塊娄猫,就必須先有個package.json文件贱除,它是Node對
  //  包進行管理需要用到的文件,先通過npm init來創(chuàng)建這個json文件
  // 2.如果這個json文件中有一些依賴的話媳溺,需要通過npm install來下載這些依賴
  output: {
    //__dirname(注意注意:這個dirname前面是有兩個下劃線的)是Node上下文的一個
    // 全局變量月幌,保存著webpack.config.js這個文件的絕對路徑,path模塊中有個
    // resolve方法可以進行路徑拼接悬蔽,就可以拼接出輸出絕對路徑了
    path:path.resolve(__dirname,"dist"),
    filename:"bundle.js",
    // publicPath:"dist/"
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        //1.css-loader只負責css文件加載扯躺,不會解析
        //2.style-loader負責將樣式添加到DOM中
        //使用多個loader時,webpack是從右向左讀的蝎困,
        // 若是沒使用css-loader解析就用style-loader會直接報錯
        //所以順序不能亂
        use: ['style-loader','css-loader']
      },
      {
        test: /\.less$/,
        use: [{
          loader: "style-loader" // creates style nodes from JS strings
        }, {
          loader: "css-loader" // translates CSS into CommonJS
        }, {
          loader: "less-loader" // compiles Less to CSS
        }]
      },
      {
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              //當加載的圖片小于limit時录语,會將圖片編譯成base64的字符串形式
              //當加載的圖片大于limit時,就會去使用file-loader來加載
              limit: 8196,//文件的大小8kb
              name:"img/[name].[hash:8].[ext]"
            }
          }
        ]
      },
      {
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['es2015']
          }
        }
      },
      {
        test: /\.vue$/,
        use:['vue-loader']
      }
    ]
  },
  resolve:{
    //別名
    alias:{
      //在import的時候會去這個文件夾中找
      'vue$':"vue/dist/vue.esm.js"
    },
    //后綴名
    extensions:['.js','.less','.css','.vue']
  },
  plugins:[
      new webpack.BannerPlugin('最終版權(quán)歸XXX所有'),
      new htmlWebpackPlugin({
        template:'index.html'
      })
  ],
};

開發(fā)時配置禾乘,因為只有開發(fā)時需要webpack-dev-server

module.exports = {
  devServer:{
    contentBase:"./dist",
    inline:true
  }
};

發(fā)布時依賴澎埠,只有發(fā)布時才需要Js丑化

const uglifyJsPlugin = require("uglifyjs-webpack-plugin");
module.exports = {
  plugins:[
      new uglifyJsPlugin()
  ],
};

為了合并配置文件,還需要一個工具始藕,webpack-merge

安裝:

cnpm install webpack-merge --save-dev

然后使用webpack-merge進行配置文件的合并

const uglifyJsPlugin = require("uglifyjs-webpack-plugin");
const WebpackMerge = require("webpack-merge");
const baseConfig = require("./base.config");

module.exports = WebpackMerge(baseConfig,{
  plugins:[
      new uglifyJsPlugin()
  ],
});
const WebpackMerge = require("webpack-merge");
const baseConfig = require("./base.config");

module.exports = WebpackMerge(baseConfig,{
  devServer:{
    contentBase:"./dist",
    inline:true
  }
});

好的蒲稳,現(xiàn)在webpack.config.js可以退役了

const path = require("path");
const webpack = require("webpack");
const htmlWebpackPlugin = require("html-webpack-plugin");
const uglifyJsPlugin = require("uglifyjs-webpack-plugin");
module.exports = {
  //需要打包的文件氮趋,入口JS文件
  entry: "./src/main.js",
  //1.入口文件可以直接寫當前路徑的main.js文件,直接寫相對路徑就可以江耀,
  // 就是相對于webpack.config.js的路徑
  //2.output是出口剩胁,這需要一個對象
  //包括這個輸出文件的地址path和文件名filename
  //dist是distribute發(fā)布的意思
  //3.path是一個絕對路徑,那么肯定不要自己把它給寫死了祥国,應該是動態(tài)獲取的
  //Node里有個叫做path的模塊昵观,path就能拿到當前webpack.config.js的路徑
  //所以要先下載這個依賴。
  // 1.想要使用Node里面的模塊系宫,就必須先有個package.json文件索昂,它是Node對
  //  包進行管理需要用到的文件,先通過npm init來創(chuàng)建這個json文件
  // 2.如果這個json文件中有一些依賴的話扩借,需要通過npm install來下載這些依賴
  output: {
    //__dirname(注意注意:這個dirname前面是有兩個下劃線的)是Node上下文的一個
    // 全局變量椒惨,保存著webpack.config.js這個文件的絕對路徑,path模塊中有個
    // resolve方法可以進行路徑拼接潮罪,就可以拼接出輸出絕對路徑了
    path:path.resolve(__dirname,"dist"),
    filename:"bundle.js",
    // publicPath:"dist/"
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        //1.css-loader只負責css文件加載康谆,不會解析
        //2.style-loader負責將樣式添加到DOM中
        //使用多個loader時,webpack是從右向左讀的嫉到,
        // 若是沒使用css-loader解析就用style-loader會直接報錯
        //所以順序不能亂
        use: ['style-loader','css-loader']
      },
      {
        test: /\.less$/,
        use: [{
          loader: "style-loader" // creates style nodes from JS strings
        }, {
          loader: "css-loader" // translates CSS into CommonJS
        }, {
          loader: "less-loader" // compiles Less to CSS
        }]
      },
      {
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              //當加載的圖片小于limit時沃暗,會將圖片編譯成base64的字符串形式
              //當加載的圖片大于limit時,就會去使用file-loader來加載
              limit: 8196,//文件的大小8kb
              name:"img/[name].[hash:8].[ext]"
            }
          }
        ]
      },
      {
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['es2015']
          }
        }
      },
      {
        test: /\.vue$/,
        use:['vue-loader']
      }
    ]
  },
  resolve:{
    //別名
    alias:{
      //在import的時候會去這個文件夾中找
      'vue$':"vue/dist/vue.esm.js"
    },
    //后綴名
    extensions:['.js','.less','.css','.vue']
  },
  plugins:[
      new webpack.BannerPlugin('最終版權(quán)歸XXX所有'),
      new htmlWebpackPlugin({
        template:'index.html'
      }),
      new uglifyJsPlugin()
  ],
  devServer:{
    contentBase:"./dist",
    inline:true
  }
};

不過現(xiàn)在直接打包的話會報錯的何恶,因為webpack默認的配置文件名為webpack.config.js孽锥,你把它刪除了,自然就報錯了细层,所以現(xiàn)在需要在package.json中配置一下webpack的配置文件的名字

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --config ./build/prod.config.js",
    "dev": "webpack-dev-server --open --config ./build/dev.config.js"
  },

現(xiàn)在就可以打包了惜辑,不過還有個地方需要改

path:path.resolve(__dirname,"dist"),

--dirname表示配置文件當前的路徑,現(xiàn)在變成build文件夾疫赎,所以"dist"要改成"../dist"盛撑,表示到打包到build的上級目錄

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市捧搞,隨后出現(xiàn)的幾起案子抵卫,更是在濱河造成了極大的恐慌,老刑警劉巖胎撇,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件介粘,死亡現(xiàn)場離奇詭異,居然都是意外死亡晚树,警方通過查閱死者的電腦和手機碗短,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來题涨,“玉大人偎谁,你說我怎么就攤上這事「俣拢” “怎么了巡雨?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長席函。 經(jīng)常有香客問我铐望,道長,這世上最難降的妖魔是什么茂附? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任正蛙,我火速辦了婚禮,結(jié)果婚禮上营曼,老公的妹妹穿的比我還像新娘乒验。我一直安慰自己,他們只是感情好蒂阱,可當我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布锻全。 她就那樣靜靜地躺著,像睡著了一般录煤。 火紅的嫁衣襯著肌膚如雪鳄厌。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天妈踊,我揣著相機與錄音了嚎,去河邊找鬼。 笑死廊营,一個胖子當著我的面吹牛歪泳,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播赘风,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼夹囚,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了邀窃?” 一聲冷哼從身側(cè)響起荸哟,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎瞬捕,沒想到半個月后鞍历,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡肪虎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年劣砍,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扇救。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡刑枝,死狀恐怖香嗓,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情装畅,我是刑警寧澤靠娱,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站掠兄,受9級特大地震影響像云,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蚂夕,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一迅诬、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧婿牍,春花似錦侈贷、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至慎菲,卻和暖如春嫁蛇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背露该。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工睬棚, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人解幼。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓抑党,卻偏偏與公主長得像,于是被迫代替她去往敵國和親撵摆。 傳聞我的和親對象是個殘疾皇子底靠,可洞房花燭夜當晚...
    茶點故事閱讀 43,446評論 2 348