從零開始畅涂,配置webpack4

webpack版本:4.8.3
webpack-cli版本:2.1.3
1.全局安裝webpack和webpack-cli
cnpm i webpack webpack-cli -g
2.新建一個項目, 然后初始化
cnpm init
然后會生成一個package.json和 package-lock.json
3.在項目本地安裝webpack和webpack-cli
cnpm i webpack webpack-cli -D
注: -D是--save-dev的縮寫
-S是--save的縮寫
區(qū)別:-D是只在開發(fā)環(huán)境即dev中使用茅坛,項目發(fā)布以后就不會使用到冠息,如babel,loader等
-S是在開發(fā)和正式環(huán)境都會用到役衡,如jq,Vue等
4.打包第一個js文件
在根目錄新建一個hello.js文件薪棒,然后執(zhí)行
webpack hello.js hello.bundle.js
會得到一個警告一個錯誤

error1.png

這是因為webpack4與之前不太一樣
webpack4.x的打包已經(jīng)不能用
webpack 文件a 文件b
的方式手蝎,而是直接運行
webpack --mode development(開發(fā)環(huán)境)
或者
webpack --mode production(發(fā)布模式)榕莺,
這是 webpack 4 引入的模式,包括 development棵介、production钉鸯、none 三個值,我們不傳入值的話邮辽,默認(rèn)使用 production進(jìn)行打包唠雕。
我們可以在package.json,script字段中添加以下設(shè)置:
"dev":"webpack --mode development", "build":"webpack --mode production"
這樣吨述,我們就能直接使用命令 npm run dev 或 npm run build 來進(jìn)行文件的打包處理岩睁。
webpack4.x會以項目根目錄下'./src/index.js'作為入口,單單創(chuàng)建src文件夾或者沒有index.js文件都會報錯揣云,輸出路徑是'./dist/main.js'捕儒,dist目錄及main.js會自動生成。
5.打包一個css文件
安裝
css-loader:使webpack可以處理css文件
style-loader:新建一個style標(biāo)簽邓夕,把css-loader處理過的文件放進(jìn)去刘莹,然后插入到HTML標(biāo)簽中
第一種方法:
在js文件中引入css文件,然后在文件名之前添加對應(yīng)的loader
require('style-loader!css-loader!./style.css')
第二種方法:
在執(zhí)行webpack命令時添加
webpack --mode development --module-bind "css=style-loader!css-loader"
其他的一些參數(shù)
--watch:監(jiān)控文件變化焚刚,一旦文件有變化点弯,就重新構(gòu)建。但默認(rèn)情況下矿咕,watch 選項是禁用的抢肛。
--progerss:會出現(xiàn)打包過程,有百分比進(jìn)度條
--display-modules:會把所有打包的模塊列出來
--display-reasons:會把打包的原因列出來
第三種方法:
添加webpack配置文件痴腌,稍后會寫出雌团。
6.添加配置文件
webpack4學(xué)習(xí)了parcel的0配置燃领,所以也可以不需要配置文件
這里webpack的配置文件并沒有太大變化

// 單入口文件
const path = require('path')

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'main.js'
  }
}
// 多入口文件
const path = require('path')

module.exports = {
  entry: {
    main: './src/index.js',
    a: './src/a.js'
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].js'
  }
}

注意:1.輸出路徑是path.resolve(__dirname, 'dist')
2.多文件的輸出文件名不能固定
3.如果不寫入口出口路徑則使用webpack4默認(rèn)的路徑
7.添加加載loaders
1.預(yù)處理css士聪,less
安裝less,less-loader猛蔽,css-loader剥悟,style-loader,postcss-loader和autoprefixer
cnpm install less less-loader css-loader style-loader postcss-loader autoprefixer -D
然后添加模塊曼库,規(guī)則

module: {
    rules: [
      {
        test: /\.less$/,
        loader: 'style-loader!css-loader!postcss-loader!less-loader'  // 從右到左執(zhí)行区岗,所以注意順序  
      }
    ]
  }

為了加webkit等前綴需要在webpack.config同級下創(chuàng)建一個postcss.config.js文件導(dǎo)入autoprefixer自動補(bǔ)全

module.exports = {
  plugins: [
    require('autoprefixer')
  ]
}

還需在package.json文件中添加判斷瀏覽器版本

"browserslist": [
    "> 1%",       // 全球瀏覽器使用率大于1%,最新兩個版本并且是IE8以上的瀏覽器毁枯,加前綴  
    "last 2 versions",
    "not ie <= 8"
  ]

8.加入babel對es6語法進(jìn)行轉(zhuǎn)譯
cnpm install babel-loader babel-core babel-preset-env --save-dev

{
        test: /\.js$/,               // 匹配js文件
        loader: 'babel-loader',
        exclude: path.resolve(__dirname, 'node_modules'),    //匹配時忽略這個目錄慈缔,提高打包速度
        include: path.resolve(__dirname, 'src'),             // 匹配時查找的范圍
        query: {
          presets: ['env']
        }
      }

9.開啟實時更新
安裝wbepack-dev-server
cnpm i webapck-dev-server -D
為了每次編譯完成后刪除上次打包的結(jié)果,添加刪除插件clean-webpack-plugin种玛,但是他也會刪除我們的index.html藐鹤,所以還需要安裝自動生成html插件
cnpm i clean-webpack-plugin html-webpack-plugin -D

const Webpack = require('webpack')
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

// devServer和plugins是與module同級的
entry:,
output: ,
module: {
    rules: []
},
devServer: {
    // 設(shè)置服務(wù)器訪問的基本目錄
    contentBase: path.resolve(__dirname, 'dist'), //最好設(shè)置成絕對路徑
    // 設(shè)置服務(wù)器的ip地址,可以是localhost
    host: 'localhost',
    // 設(shè)置端口
    port: 8090,
    // 設(shè)置自動打開瀏覽器
    open: true,
    // 設(shè)置自動更新
    hot: true
  },
  plugins: [
    new Webpack.HotModuleReplacementPlugin(),
    new CleanWebpackPlugin(['dist']), //傳入數(shù)組,指定要刪除的目錄
    new HtmlWebpackPlugin({
      template: './index.html',               // 會與根目錄下的index.html相關(guān)聯(lián)瓤檐,把根目錄下index的東西都放到生成的HTML中
      filename: 'index.html',         // 生成的HTML名,路徑為上面output中的path娱节,不填默認(rèn)是index.html
      title: '測試webpack',
      hash: true,
      chunks: ['main'],  // 多頁面分別引入自己的js
      minify: {
        collapseWhitespace: true,  //折疊空白區(qū)域 也就是壓縮代碼
        removeComments: true, //移除HTML中的注釋
      }
    })
  ]

注意:熱更新只針對js文件和樣式文件挠蛉,html不能熱更新
10.仔細(xì)講下html-webpack-plugin
多頁面時需要寫多個new HtmlWebpackPlugin

    new HtmlWebpackPlugin({
      template: './index.html',               // 會與根目錄下的index.html相關(guān)聯(lián),把根目錄下index的東西都放到生成的HTML中
      filename: 'index.html',         // 生成的HTML名肄满,路徑為上面output中的path谴古,不寫默認(rèn)為index.html
      title: '測試webpack',
      hash: true,
      //inject: 'body', //指定鏈接注入在<head>標(biāo)簽中還是<body>標(biāo)簽中,為false值時表示不自動注入文件中稠歉,需要手動設(shè)置
      chunks: ['main'],  // 多頁面分別引入自己的js
      minify: {
        collapseWhitespace: true //折疊空白區(qū)域 也就是壓縮代碼
      }
    }),
    new HtmlWebpackPlugin({
      template: './index.html',               // 會與根目錄下的index.html相關(guān)聯(lián)掰担,把根目錄下index的東西都放到生成的HTML中
      filename: 'a.html',         // 生成的HTML名,路徑為上面output中的path轧抗,不寫默認(rèn)為index.html
      title: '測試webpack',
      hash: true,
      //inject: 'body', //指定鏈接注入在<head>標(biāo)簽中還是<body>標(biāo)簽中恩敌,為false值時表示不自動注入文件中,需要手動設(shè)置
      chunks: ['main', 'a'],  // 多頁面分別引入自己的js
      minify: {
        collapseWhitespace: true //折疊空白區(qū)域 也就是壓縮代碼
      }
    })

還可通過這種方式自己引入

<% for (var chunk in htmlWebpackPlugin.files.chunks) { %>
<script type="text/javascript" src="<%=htmlWebpackPlugin.files.chunks[chunk].entry %>"></script>
<% } %>

11.添加vue
安裝vue
cnpm install vue -S
安裝vue-loader
cnpm install vue-loader -D
創(chuàng)建一個.vue后綴的文件横媚,然后修改main.js文件

import Vue from 'vue'
import App from './app.vue'
const root = document.createElement('div')
document.body.appendChild(root)
new Vue({
  render: (h) => h(App)
}).$mount(root)

然后修改webpack.config文件纠炮,添加vue-loader
注意:vue-loader15.0版本之后需要獨立引入VueLoaderPlugin

const VueLoaderPlugin = require('vue-loader/lib/plugin')
{
        test: /\.vue$/,
        loader: 'vue-loader'
}

如果你沒有安裝css預(yù)處理,或者在style部分沒有添加lang=*灯蝴,這時打包會報錯

error.png

明顯這是未對vue文件中的style部分正確的編譯恢口,所以安裝vue-style-loader并添加loader

cnpm install vue-style-loader -D
{
        test: /\.css$/,
        use: [
          'vue-style-loader',
          'css-loader'
        ]
      },

注意:如果在main.js中的寫法和vue-cli官方腳手架一樣是這樣的

new Vue({
  el: '#app',
  components: {App},
  template: '<App/>'
})

則運行dev會出現(xiàn)警告


warn.png

如果在代碼中要使用到template編譯模版(比如傳入一個字符串給 template 選項,或掛載到一個元素上并以其 DOM 內(nèi)部的 HTML 作為模板)穷躁,則需要完整版的vue耕肩。
當(dāng)使用 vue-loader 或 vueify 的時候,*.vue 文件內(nèi)部的模板會在構(gòu)建時預(yù)編譯成 JavaScript问潭。你在最終打好的包里實際上是不需要編譯器的猿诸,所以只用運行時版本即可。
因為運行時版本相比完整版體積要小大約 30%狡忙,所以應(yīng)該盡可能使用這個版本梳虽。如果你仍然希望使用完整版,則需要在webpack.config里配置一個別名:

module.exports = {
  // ...
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    }
  }
}

12.在vue文件里添加圖片
在vue文件中添加圖片灾茁,然后打包會報錯

error.png

提示我們?nèi)鄙賔ile-loader窜觉,安裝即可,且不用添加loader到webpack.config文件
cnpm i file-loader -D
打包時對圖片的編譯我們使用url-loader北专,他會將圖片轉(zhuǎn)為base64格式添加到網(wǎng)頁中禀挫,url-loader也依賴于file-loader,所以也需要安裝file-loader

cnpm i url-loader file-loader -D
{
        test: /\.(gif|jpg|jpeg|png|svg)$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 1024, //表示圖片最大為1024KB 
              name: '[name].[ext]'  // 生成的文件名
            }
          }
        ]
      }

13.根據(jù)多環(huán)境選擇不同的配置
安裝cross-env
cnpm i cross-env -D
修改package.json文件

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "cross-env NODE_ENV=development webpack-dev-server --mode development",
    "build": "cross-env NODE_ENV=production webpack --mode production"
  },

這里的NODE_ENV會添加到process.env上拓颓,怎么添加呢语婴?

const isDev = process.env.NODE_ENV === 'development'
const devAPI = '"http://localhost:8080"'
const proAPI = '"http://localhost:3000"'
// 注意一定是單引號加雙引號的形式
...
plugins: {
...
new Webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: isDev ? '"development"' : '"production"',
        API_HOST: isDev ? devAPI : proAPI
      }
    })
...
}

另外可以將整個對象命名為config,然后根據(jù)isdev去給config添加配置,最后再將config暴露出去

const config = {......}
if(isDev){
  config.devtool = '#cheap-module-eval-source'
}
module.exports = config

14.將css單獨打包
安裝extract-text-webpack-plugin
注意:webpack4中需要使用的extract-text-webpack-plugin版本比較高砰左,需要指定版本
查看包的所有版本
cnpm view extract-text-webpack-plugin versions
安裝包的最新版本
cnpm i extract-text-webpack-plugin@next -D

const ExtractTextPlugin = require('extract-text-webpack-plugin')
...
{
        test: /\.less$/,
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: [
            'css-loader',
            {
              loader: 'postcss-loader',
              options: {
                sourceMap: true
              },
            },
            'less-loader'
          ]
        })
}
...
plugins:  {
    new ExtractTextPlugin({
        filename: 'css/app.[hash].css',
        chunkFilename: 'css/app.[contenthash].css'
}

webpack4中extract-text-webpack-plugin已經(jīng)不再被推薦使用画拾,推薦使用新的插件mini-css-extract-plugin
安裝mini-css-extract-plugin
cnpm i mini-css-extract-plugin -D

const MiniCssExtractPlugin = require('mini-css-extract-plugin')
...
{
        test: /\.less$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          {
            loader: 'postcss-loader',
            options: {
              sourceMap: true
            },
          },
          'less-loader'
        ]
      },
...
new MiniCssExtractPlugin({
      filename: 'static/css/app.[hash].css',
      chunkFilename: 'static/css/app.[contenthash].css'
    })

15.將第三方庫單獨打包(不是很明白)
因為CommonsChunkPlugin被刪除, 改為內(nèi)置的api--optimization,同plugins同級

...
  optimization: {
    splitChunks: {
      cacheGroups: {
        vendor: {
          name: 'vendor',
          chunks: 'initial',
          minChunks: 2
        },

      }
    }
  },
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市菜职,隨后出現(xiàn)的幾起案子青抛,更是在濱河造成了極大的恐慌,老刑警劉巖酬核,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蜜另,死亡現(xiàn)場離奇詭異,居然都是意外死亡嫡意,警方通過查閱死者的電腦和手機(jī)举瑰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蔬螟,“玉大人此迅,你說我怎么就攤上這事【山恚” “怎么了耸序?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長鲁猩。 經(jīng)常有香客問我坎怪,道長,這世上最難降的妖魔是什么廓握? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任搅窿,我火速辦了婚禮,結(jié)果婚禮上隙券,老公的妹妹穿的比我還像新娘男应。我一直安慰自己,他們只是感情好娱仔,可當(dāng)我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布沐飘。 她就那樣靜靜地躺著,像睡著了一般拟枚。 火紅的嫁衣襯著肌膚如雪薪铜。 梳的紋絲不亂的頭發(fā)上众弓,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天恩溅,我揣著相機(jī)與錄音,去河邊找鬼谓娃。 笑死脚乡,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播奶稠,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼俯艰,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了锌订?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎谦铃,沒想到半個月后卓嫂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡蜈项,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年芹关,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片紧卒。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡侥衬,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出跑芳,到底是詐尸還是另有隱情轴总,我是刑警寧澤,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布博个,位于F島的核電站肘习,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏坡倔。R本人自食惡果不足惜漂佩,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望罪塔。 院中可真熱鬧投蝉,春花似錦、人聲如沸征堪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽佃蚜。三九已至庸娱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間谐算,已是汗流浹背熟尉。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留洲脂,地道東北人斤儿。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親往果。 傳聞我的和親對象是個殘疾皇子疆液,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,044評論 2 355

推薦閱讀更多精彩內(nèi)容