webpack從零開始第1課:安裝webpack和webpack-dev-server

webpack目錄javascript


本文參考文檔css


前提條件html

  • 電腦裝了一個全新的nodejs,最好是LTS版本,舊的nodejs版本可能沒使用webpack的新功能,也可能會丟失一些依賴的包
  • 先安裝好淘寶的cnpm,淘寶鏡像方便些$ npm install -g cnpm --registry=https://registry.npm.taobao.org
  • 個人安裝環境是win10

一:安裝webpack和webpack-dev-server

1.準備工做

  • 新建項目文件夾D:\03www2018\study\webpack2017 下面簡寫爲 根目錄
  • 新建npm配置文件package.josn,根目錄>cnpm init

2.項目局部安裝webpack和webpack-dev-server

  • 不建議全局安裝webpack和webpack-dev-server
  • 局部安裝webpack 根目錄>cnpm i webpack -D
  • 局部安裝server 根目錄>cnpm i webpack-dev-server -D
  • 會自動生成node_modules文件夾,下有804個文件夾(485+319server)個文件夾,這些包都是webpack的依賴
  • package.json中增長了剛安裝的包webpack的配置
"devDependencies": {
  "webpack": "^3.10.0",
  "webpack-dev-server": "^2.9.7"
}
說明1: devDependencies是開發依賴,只會在打包過程當中用到,不會包含到最後的代碼中
說明2: 若是想安裝指定版本的webpack,使用npm install --save-dev webpack@<版本號>格式

3.熟悉webpack命令行各參數的意思

  • 有關命令行各參數的用法,根目錄>"node_modules/.bin/webpack" -h
  • 上面這個執行webpack很不方便,修改根目錄>package.json,在script加上兩條
"scripts": {
    "a" :"webpack --config ./build/webpack.dev.conf.js",
    "b" :"webpack-dev-server --config ./build/webpack.dev.conf.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  • 命令行的選項其實均可以寫在配置文件webpack.config.js中,寫在配置文件中更方便更強大。webpack啓動時要讀取配置文件,參數--config指定讀取哪一個配置文件,若是沒有使用--config指定,會默認在根目錄中找webpack.config.jswebpackfile.js這個文件,有關配置文件的命名隨意定,但最好帶上環境,如webpack.base|dev|prod.conf.js
01: 配置選項 Config options:
  --config       配置文件路徑,字符串格式,默認是`根目錄`下的 webpack.config.js 或 webpackfile.js,
  --config-name  使用配置的名字,字符串
  --env          當配置文件輸出的是一個函數時,要指定,在下一節課中會介紹

02: 基本選項 Basic options:
  --context    入口文件根目錄,默認爲當前目錄
  --entry      入口文件,這裏只能是字符串,但在配置文件中還能夠定義數組或對象
  --watch, -w  監視是否有文件有改動,會自動打包,默認爲false
  --debug      Switch loaders to debug mode                            [boolean]
  --devtool    Enable devtool for better debugging experience (Example:
               --devtool eval-cheap-module-source-map)                  [string]
  -d           shortcut for --debug --devtool eval-cheap-module-source-map
               --output-pathinfo                                       [boolean]
  -p           shortcut for --optimize-minimize --define
               process.env.NODE_ENV="production"                       [boolean]
  --progress   Print compilation progress in percentage                [boolean]

03: 模塊選項 Module options:
  --module-bind       Bind an extension to a loader                     [string]
  --module-bind-post                                                    [string]
  --module-bind-pre                                                     [string]

04: 輸出選項 Output options:
  --output-path                 The output path for compilation assets
                                       [string] [default: The current directory]
  --output-filename             The output filename of the bundle
                                                   [string] [default: [name].js]
  --output-chunk-filename       The output filename for additional chunks
       [string] [default: filename with [id] instead of [name] or [id] prefixed]
  --output-source-map-filename  The output filename for the SourceMap   [string]
  --output-public-path          The public path for the assets          [string]
  --output-jsonp-function       The name of the jsonp function used for chunk
                                loading                                 [string]
  --output-pathinfo             Include a comment with the request for every
                                dependency (require, import, etc.)     [boolean]
  --output-library              Expose the exports of the entry point as library
                                                                        [string]
  --output-library-target       The type for exposing the exports of the entry
                                point as library                        [string]

05: 高級選項 Advanced options:
  --records-input-path       Path to the records file (reading)         [string]
  --records-output-path      Path to the records file (writing)         [string]
  --records-path             Path to the records file                   [string]
  --define                   Define any free var in the bundle          [string]
  --target                   The targeted execution environment         [string]
  --cache                    Enable in memory caching
                      [boolean] [default: It's enabled by default when watching]
  --watch-stdin, --stdin     Exit the process when stdin is closed     [boolean]
  --watch-aggregate-timeout  Timeout for gathering changes while watching
  --watch-poll               The polling interval for watching (also enable
                             polling)                                   [string]
  --hot                      Enables Hot Module Replacement            [boolean]
  --prefetch                 Prefetch this request (Example: --prefetch
                             ./file.js)                                 [string]
  --provide                  Provide these modules as free vars in all modules
                             (Example: --provide jQuery=jquery)         [string]
  --labeled-modules          Enables labeled modules                   [boolean]
  --plugin                   Load this plugin                           [string]
  --bail                     Abort the compilation on first error
                                                       [boolean] [default: null]
  --profile                  Profile the compilation and include information in
                             stats                     [boolean] [default: null]

06: 解析選項 Resolving options:
  --resolve-alias         Setup a module alias for resolving (Example:
                          jquery-plugin=jquery.plugin)                  [string]
  --resolve-extensions    Setup extensions that should be used to resolve
                          modules (Example: --resolve-extensions .es6,.js)
                                                                         [array]
  --resolve-loader-alias  Setup a loader alias for resolving            [string]

07: 優化選項 Optimizing options:
  --optimize-max-chunks      Try to keep the chunk count below a limit
  --optimize-min-chunk-size  Try to keep the chunk size above a limit
  --optimize-minimize        Minimize javascript and switches loaders to
                             minimizing                                [boolean]

08: 統計選項 Stats options:
  --color, --colors               Enables/Disables colors on the console
                                           [boolean] [default: (supports-color)]
  --sort-modules-by               Sorts the modules list by property in module
                                                                        [string]
  --sort-chunks-by                Sorts the chunks list by property in chunk
                                                                        [string]
  --sort-assets-by                Sorts the assets list by property in asset
                                                                        [string]
  --hide-modules                  Hides info about modules             [boolean]
  --display-exclude               Exclude modules in the output         [string]
  --display-modules               Display even excluded modules in the output
                                                                       [boolean]
  --display-max-modules           Sets the maximum number of visible modules in
                                  output                                [number]
  --display-chunks                Display chunks in the output         [boolean]
  --display-entrypoints           Display entry points in the output   [boolean]
  --display-origins               Display origins of chunks in the output
                                                                       [boolean]
  --display-cached                Display also cached modules in the output
                                                                       [boolean]
  --display-cached-assets         Display also cached assets in the output
                                                                       [boolean]
  --display-reasons               Display reasons about module inclusion in the
                                  output                               [boolean]
  --display-depth                 Display distance from entry point for each
                                  module                               [boolean]
  --display-used-exports          Display information about used exports in
                                  modules (Tree Shaking)               [boolean]
  --display-provided-exports      Display information about exports provided
                                  from modules                         [boolean]
  --display-optimization-bailout  Display information about why optimization
                                  bailed out for modules               [boolean]
  --display-error-details         Display details about errors         [boolean]
  --display                       Select display preset (verbose, detailed,
                                  normal, minimal, errors-only, none)   [string]
  --verbose                       Show more details                    [boolean]

09: 選項 Options:
  --help, -h     顯示幫助信息                                            
  --version, -v  版本號                                  
  --json, -j     將結果以JSON格式顯示

4.準備項目文件夾及文件

爲了更好地演示和學習webpack,請建好下列文件夾和文件vue

項目根目錄
│   package.json
├───node_modules
│       └╌╌ 下面是npm包
├───dist
│     └╌╌╌╌╌logo.jpg 
├───build
│   ├╌╌╌╌╌ build.js
│   ├╌╌╌╌╌ webpack.base.conf.js
│   ├╌╌╌╌╌ webpack.dev.conf.js
│   └╌╌╌╌╌ webpack.prod.conf.js
├───src
│   ├╌╌╌╌╌ main.js
│   └╌╌╌╌╌tmp
│         ├╌╌╌╌╌home.js
│         ├╌╌╌╌╌about.js
│         └╌╌╌╌╌contact.js
│   └╌╌╌╌╌template
│         └╌╌╌╌╌daqi.html // 爲hmtl插件的模板
│   └╌╌╌╌╌images
│         └╌╌╌╌╌logo.jpg

先只需寫這幾個文件,後面會陸續補充html5

二:打包

準備配置文件

  • 根目錄/build/webpack.dev.conf.js的內容以下,這是史上最簡單的配置文件了
module.exports = {
    entry: './src/main', //main.js中的.js能夠省略,前面的./不能省
    output:{
        filename:'./dist/app.js' // dist文件夾不存在時,會自動建立
    }
}
  • 根目錄/src/main.js中隨便寫一句
console.log('hello,歡迎來到零和壹在線課堂')

打包

D:\03www2018\study\webpack2017>npm run a,顯示以下java

> webpack2017@1.0.0 a D:\03www2018\study\webpack2017
> webpack --config ./build/webpack.dev.conf.js

Hash: 94dc0f2301921649904c  // complication的hash值,它的長度和算法由output中相應的項決定
Version: webpack 3.10.0 // webpack的版本
Time: 55ms // 打包花費的時間
        Asset    Size  Chunks             Chunk Names
./dist/app.js  2.5 kB       0  [emitted]  main //單個文件和數組的chunk名字默認爲main 
   [0] ./src/main.js 32 bytes {0} [built]

打開打包後的文件看下,總體是一個自執行文件,每一個文件是一個模塊作爲自執行函數的參數node

三:開啓服務器

先啓動看下,根目錄>npm run b
從啓動的信息中能夠看到,它包含了上面的打包,項目的網址是http://localhost:8080/,能夠在瀏覽器中打開看下效果,但因爲沒有指定入口文件,因此會顯示當前目錄的內容,有一點必須明白,服務器打包的後的文件並無物理存在電腦上,只是在內存中,爲了方便教程的講解,在這裏先講下服務器的配置,有關所有配置的講解,請參考下一篇文章:配置文件詳解react

3.1 使用HtmlWebpackPlugin插件生成首頁

首頁通常爲一個html文件,咱們到如今尚未定義,爲了方便,順便提早了解一下webpack的插件功能,我這裏使用HtmlWebpackPlugin來生成首頁,插件的使用基本相同,分如下幾步jquery

  • 第一步安裝 根目錄>cnpm i -D html-webpack-plugin
  • 修改配置文件 根目錄/build/webpack.dev.conf.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin'); //第二步導入
module.exports = {
    entry: './src/main', //main.js中的js能夠省略,前面的./不能省
    output:{
        filename:'./dist/[hash]app.js',
        hashDigestLength: 8 // 默認長度是20
    },
    plugins: [new HtmlWebpackPlugin], //第三步,實例化後放在plugins這個數組中就行
    devServer: {
      contentBase: path.join(__dirname, "../dist"), //網站的根目錄爲 根目錄/dist,若是配置不對,會報Cannot GET /錯誤
      port: 9000, //端口改成9000
      open:true // 自動打開瀏覽器,適合懶人
    }
}

生成的html文件只在內存中,並無存在物理磁盤上,來看一下生成的內容,留心下生成的js文件中的hash值,它的長度是8位,就是上面hashDigestLength: 8定義的webpack

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Webpack App</title>
  </head>
  <body>
  <script type="text/javascript" src="./dist/4e0c807aapp.js"></script></body>
</html>

html-webpack-plugin的用途

  • 對於打包的文件名中有hash的,這個插件是必選,由於每次源文件修改,打包後的名字就不同
  • 生成一個html5模板文件,可適用於lodash模板,也能夠利用本身定義的加載器
  • js注入,打包後的js文件會自動注入到html文件的body結尾部分(默認,也能夠注入到head部分)
  • css文件注入,假如你使用ExtractTextPlugin插件(這個插件也是必需要了解的)將css文件是單獨剝離出來,不放在html中的style標籤內,它會自動將css連接注入到link標籤中

html-webpack-plugin插件完整配置

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const HtmlWebpackPluginConfig={
    title: 'hello,零和壹在線課堂', // html5文件中<title>部分
    filename: 'front.html', // 默認是index.html,服務器中設置的首頁是index.html,若是這裏改爲其它名字,那麼devServer.index改成和它同樣,最終完整文件路徑是output.path+filename,若是filename中有子文件夾形式,如`./ab/cd/front.html`,只取`./front.html`
    template: './src/template/daqi.html', //若是以爲插件默認生成的hmtl5文件不合要求,能夠指定一個模板,模板文件若是不存在,會報錯,默認是在項目根目錄下找模板文件,才模板爲樣板,將打包的js文件注入到body結尾處
    inject:head, // true|body|head|false,四種值,默認爲true,true和body相同,是將js注入到body結束標籤前,head將打包的js文件放在head結束前,false是不注入,這時得要手工在html中加js
}
module.exports = {
    entry: './src/main', //main.js中的js能夠省略,前面的./不能省
    output:{
        filename:'./dist/[hash]app.js',
        hashDigestLength: 8
    },
    plugins: [new HtmlWebpackPlugin(HtmlWebpackPluginConfig)], //先不配置插件,看看效果
    devServer: {
      contentBase: path.join(__dirname, "../dist"), //網站的根目錄爲 根目錄/dist
      port: 9000, //端口改成9000
      open:true, // 自動打開瀏覽器
      index:'front.html' // 與HtmlWebpackPlugin中配置filename同樣
    }
}

3.2 devServer經常使用配置

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const HtmlWebpackPluginConfig={
    title: 'hello,零和壹在線課堂', // html5文件中<title>部分
    filename: 'front.html', // 默認是index.html,服務器中設置的首頁是index.html,若是這裏改爲其它名字,那麼devServer.index改成和它同樣
    template: './src/template/daqi.html', // 若是以爲插件默認生成的hmtl5文件不合要求,能夠指定一個模板,模板文件若是不存在,會報錯,默認是在項目根目錄下找模板文件,才模板爲樣板,將打包的js文件注入到body結尾處
    inject:'body', // true|body|head|false,四種值,默認爲true,true和body相同,是將js注入到body結束標籤前,head將打包的js文件放在head結束前,false是不注入,這時得要手工在html中加js
}
module.exports = {
    entry: './src/main', //main.js中的js能夠省略,前面的./不能省
    output:{
        filename:'./dist/[hash]app.js',
        hashDigestLength: 8
    },
    plugins: [new HtmlWebpackPlugin(HtmlWebpackPluginConfig)], //先不配置插件,看看效果
    devServer: {
      contentBase: path.join(__dirname, "../dist"), //網站的根目錄爲 根目錄/dist
      port: 9000, //端口改成9000
      host: '192.168.0.103', //若是指定的host,這樣同局域網的電腦或手機能夠訪問該網站,host的值在dos下使用ipconfig獲取 
      open:true, // 自動打開瀏覽器
      index:'front.html', // 與HtmlWebpackPlugin中配置filename同樣
      inline:true, // 默認爲true, 意思是,在打包時會注入一段代碼到最後的js文件中,用來監視頁面的改動而自動刷新頁面,當爲false時,網頁自動刷新的模式是iframe,也就是將模板頁放在一個frame中
      hot:false,
      compress:true //壓縮
    }
}

結合服務器和html插件,最後生成的配置文件以下

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack')
const HtmlWebpackPluginConfig={
    title: 'hello,零和壹在線課堂', // html5文件中<title>部分
    filename: 'front.html', // 默認是index.html,服務器中設置的首頁是index.html,若是這裏改爲其它名字,那麼devServer.index改成和它同樣
    // 也是 context+template是最後模板的完整路徑,./不能少
    template: './template/daqi.html', // 若是以爲插件默認生成的hmtl5文件不合要求,能夠指定一個模板,模板文件若是不存在,會報錯,默認是在項目根目錄下找模板文件,才模板爲樣板,將打包的js文件注入到body結尾處
    inject:'body', // true|body|head|false,四種值,默認爲true,true和body相同,是將js注入到body結束標籤前,head將打包的js文件放在head結束前,false是不注入,這時得要手工在html中加js
}


module.exports = {
    context: path.resolve(__dirname,'../src'), //D:\03www2018\study\webpack2017\build\src
    entry: './main', //main.js中的js能夠省略,前面的./不能省
    output:{
        path:path.resolve(__dirname,'../dist'),
        filename: './[hash]app.js',
        hashDigestLength: 8
    },
    module: {        
        rules: [       

            ]
      },
    plugins: [
        new HtmlWebpackPlugin(HtmlWebpackPluginConfig), // 生成首頁html5文件,外部插件須要安裝
        new webpack.DefinePlugin({BJ: JSON.stringify('北京'),}) // 內置插件,無須安裝,能夠理解爲它是webpack實例的一個方法,該插件至關於apache等web服務器上定義一個常量
    ], 
    devServer: {
      contentBase: path.resolve(__dirname, "../dist"), //網站的根目錄爲 根目錄/dist,這個路徑通常與output.path一致,由於html插件生成的html5頁是放在output.path這個目錄下
      port: 9000, //端口改成9000
      open:true, // 自動打開瀏覽器,每次啓動服務器會自動打開默認的瀏覽器
      index:'front.html', // 與HtmlWebpackPlugin中配置filename同樣
      inline:true, // 默認爲true, 意思是,在打包時會注入一段代碼到最後的js文件中,用來監視頁面的改動而自動刷新頁面,當爲false時,網頁自動刷新的模式是iframe,也就是將模板頁放在一個frame中
      hot:false,
      compress:true //壓縮
    }
}

3.3 給首頁加一張圖片

// D:\03www2018\study\webpack2017\src\template\daqi.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>大奇模板</title>
  </head>
  <body>
      <div style="background-color:#eee;font-size:16px;">歡迎來到零和壹在線課堂1234</div>
      <div id='hello'></div>
      <img src='/img/logo2.jpg' data-src='../images/logo.jpg' />  
  </body>
</html>
  • webpack,經過使用file-loader能夠將圖片當成一個模塊,使用require來導入,進一步可使用url-loader將圖片轉成base64-data
  • 使用圖片的場景大體分四種,html文件中使用src標籤,樣式的background中設定背景,js文件中元素.innerHTML='<img src="logo.jpg" />'的方式,最後一種是在vue或react等框架中使用,今天要講的是第一種,如何處理html文件src標籤中的圖片
  • html文件中圖片的處理有兩種,一種是象正常使用圖片同樣,不打包,但圖片必須放在打包生成文件目錄下,如./dist/logo.jpg,也就是最後的入口front.html文件能夠讀到的位置,在front.html中使用<img src='./logo.jpg'/>,表示logo.jpg與最後生成的front.html是同級目錄。但實際工做中,每每圖片放在與打包前的html模板文件一塊兒的,須要將圖片和html模板文件分別打包到./dist下,這使用html-loader是解決不了的,官網及網上大部分教程講得不是特別清楚,在這裏我詳細講下,這裏就要用到file-loader,不然會報錯Error: Child compilation failed: Module parse failed: Unexpected character '�' (1:0)You may need an appropriate loader to handle this file type.

第1步:安裝html-loader和file-loader,根目錄/cnpm i -D html-loader file-loader
file-loader處理require('./logo.jpg')這種類型,將圖片當成一個js模塊
html-loader是將html中src標籤中配置有特定data屬性的圖片,轉爲由require的方式來導入。也就是說,它只是標識爲哪些圖片須要由require的方式導入,但具體require導入,得須要file-loader插件,
第2步:在webpack.conf.js中配置這兩個加載器

module: {
        rules: [
        {
            test: /\.html$/, 
            use: {
                loader: 'html-loader',
                options: {
                 attrs: [':data-src']
                }
            }
        },
     {
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
                //name: '[path][name].[ext]',
                name: '[name]2.[ext]', //最後生成的文件名是 output.path+ outputPaht+ name,[name],[ext],[path]表示原來的文件名字,擴展名,路徑
                //useRelativePath:true,
                outputPath: 'img/' // 後面的/不能少
            }  
          }
        ]
      },
        ]
      },

第3步:在html文件src標籤中引用圖片
<img src='/img/logo2.jpg' data-src='../images/logo.jpg' />
這裏注意,data-src是打包前圖片位置,src是打包後圖片的url

四: 手機或其它電腦訪問該服務器

實際開發中,須要手機或其它設備如ipad即時訪問該服務器
服務器: 就是開啓webpack-dev-server這臺電腦
其它設備:下面以同一網絡下的手機爲例(同一wifi就行)
第一步:配置服務器

devServer: {
    contentBase: path.join(__dirname, "../dist"), //網站的根目錄爲 根目錄/dist,若是配置不對,會報Cannot GET /錯誤
    port: 9000, 
    open: true,
    host: '192.168.0.103' //請在dos下,輸入ipconfig能夠找到當前電腦的ip
}

第二步:在手機上找一個合適的瀏覽器,輸入 192.168.0.103:9000就能夠訪問
說明:有少數瀏覽器打開是空白網頁,我使用uc瀏覽器ok,ip地址和端口與你本身的設置有關,我上面只是個人設置


下一課: webpack從零開始第2課: 配置文件

相關文章
相關標籤/搜索