webpack教程

一、webpack和npm的关系

  • npm是包管理器,及可以执行命令包(webpack可以看成是功能强大的命令包,除了webpack还有其它如webpack-dev-server);
  • webpack可以看成是功能强大的命令包:它还可以执行其它的功能包(装载机,插件)

二、全局安装/项目安装?[1]

重点就在这个包是否要作为CMD命令来使用及本地项目是否都差不多,因此放在全局

  1. 这个包要作为CMD命令使用:要全局安装 。如yarn cnpm webpack-dev-server等

即安装到node_global,因为node_global在系统环境中配置了路径,故而里面的脚本能在cmd中直接运行
此时这个命令的运行环境是全局环境:对应全局的webpack版本

  1. 不作为CMD命令使用:项目安装

在package.json的scripts中也可以执行命令包,此时通过npm run 命令别名来执行
因为Npm会临时把本地项目命令加载到系统环境path中,故而命令包放在本地也能通过npm run来执行
如果本地有安装,则执行本地的。否则执行的是全局的命令包。对应的执行环境webpack也是一样的。

三、打包前的准备工作(操作的webpack为3.8.1)

  • 创建项目: $ npm init
  • 全局安装webpack:$ npm install webpack -g 及脚手架$ npm install webpack-cli -g

全局安装是为了CMD使用webpack 命令

  • 本地安装webpack: $ npm install webpack --save-dev

四、js的打包

方式①:$ webpack 源文件 目标文件 即:把源文件js打包到目标文件
如:$ webpack ./src/app.js ./dist/main.js

其它参数:

  • --watch 开启热跟新
  • -p 压缩目标文件
  • -d 调试时,方便定位源文件

问题:

  • 命令行太长,写法比较复杂
  • 直接采用的是webpack命令,此时,运行环境为 全局的webpack包,并非项目的webpack版本,可能会产生和项目的一些冲突

方式②:通过配置文件,来简化webpack命令

创建配置文件 webpack.config.js
module.exports={
   entry:'./src/app.js',
   output:{
      path: __dirname + '/dist', //__dirname 是Node的变量,表示根目录。注意:path只能是绝对路径
      filename: 'main.[hash:5].js' //[hash:5]表示取hash的5位,这边是为了更新浏览器本地缓存
}
//json文件不能注释,这边是为了解释说明用的

因为webpack会自动会查找webpack.config.js,且这边已经配置好了源文件及目标文件
此时可以:$ webpack 即可打包。或$ webpack --watch

问题:

  • 命令行还是不够简洁,一些参数还是没办法配置
  • (同上)直接采用的是webpack命令,此时,运行环境为 全局的webpack包,并非项目的webpack版本

方式③:通过package.json的scripts来运行脚本

修改package.json的scripts:
"scripts": {
     "build": "webpack --watch -d",
     "prod": "webpack -p"
 }

此时,可以直接$ npm run build$ npm run prod来运行脚本

优点:

  • 命令全都由npm来运行,且命令简洁明了(便于知道有哪些命令)
  • npm来运行,所以采用的是项目的脚本(包括其它的脚本也是一样)

五、结合html

前面已经学会js的打包,但毕竟运行在浏览器的入口是html,那怎么和html结合呢?

方式①:创建html,手动引入打包后的js

问题:

  • 打包后的style,script标签要手动写入html。麻烦
  • 以及hash问题,每次生成的打包文件名还不一样,又要重新写入html。麻烦

方式②:使用html-webpack-plugin插件

作用:

  • 程序还是正常从entey入口开始打包
  • 然后,对html模板,引入<script src="打包后的js">,及其它操作(压缩,hash等等)
安装插件
$ npm install html-webpack-plugin --save-dev 

使用插件(在webpack.config.js中引入及挂载)

引入:
const HtmlWebpackPlugin = require('html-webpack-plugin');

挂载:
module.exports={
plugins: [
 new HtmlWebpackPlugin({
    template:"./src/index.html", //html的模版文件
    filename: 'one.html',    //生成目标html的名字
    minify: {collapseWhitespace:true} ,//压缩html及配置压缩类型
    hash:true//会在所有注入的静态资源添加webpack每次编译产生的唯一hash值
 })
]
}

//hash:true的效果
<script type="text/javascript" src="main.dce13.js?dce1306176497ad4a85d"></script></body>
可以发现dce13:为main.[hash:5]生成的hash值
?dce1306176497ad4a85d为这次生成的hash值,所有静态文件都添加了这个

html-webpack-plugin详细配置点击查看
minify的详细配置点击查看


高级篇----多html的配置

  • 从实际意义出发,肯定需要配置多入口
之前entry是string类型,这次我们采用array类型

entry: {
   "entry1":'./src/app.js', //其中,"entry1"作为chunk代码块
   "entry2":'./src/app1.js',
   "entry3":'./src/app2.js',
},

使用插件
plugins: [  //tips: plugins执行顺序也是从后到前执行。即先执行底下的插件,再上面的插件
 new HtmlWebpackPlugin({
    template:"./src/index_other.html",
    filename: 'two.html',      //这个是第二个html的出口
    minify: {collapseWhitespace:true} ,
    hash:true,
    chunks:['entry2','entry3']  //这边测试处理两个,也可以通过excludeChunk:['entry1'] 取余
 }),
 new HtmlWebpackPlugin({
    template:"./src/index.html",
    filename: 'one.html',    
    minify: {collapseWhitespace:true} ,
    hash:true,
    chunks:['entry1']   //这个配置是要处理的chunk代码块,默认为all即所有入口的都处理
 })
]
--------------------------------------------------------
说明:
chunks:[] //数组内的值为entry配置里面的key值。这边即'entry1','entry2','entry3'
excludeChunk:[]//这个配置是除了数组内的chunk代码块会去处理。即取反

这边还有个问题:多个html-webpack-plugin插件处理入口,于是会生成多个目标js。

之前:
output:{
    path: __dirname + '/dist',
    filename: 'main.[hash:5].js' //多html-webpack-plugin插件时,会生成多个同名的该文件,会同名覆盖
}

改为=>
output:{
    path: __dirname + '/dist',
    filename: '[name].[hash:5].js' //name为对应entry的chunk名,同上
}

说明:[name]表示为对应entry的chunk名,同上

总结:对比一个html,区别在于:
需要多个入口,然后使用多个html-webpack-plugin插件处理入口对应的chunk,然后生成多html

六、结合css

前面学习了js的打包,以及把打包后的Js结合html,结合html我们采用插件来自动化帮我们处理一些事情。
但是怎么结合css呢,css不是浏览器入口,只能通过源js引入该css。再处理
但是webpack默认只认得js,因此要采用装载机来处理css,再放到html中。

方式①:使用'style-loader', 'css-loader' 。这种是<style>样式的方式

原理:

  • 在js中引入该css。import css from './one.css';
  • 然后,css-loader,实现从对应css文件导入文件到js中
  • 然后,style-loader,实现从js中,提取出css然后在html中,写入<style>中
安装装载机
$ npm install css-loader style-loader --save-dev

使用装载机(在webpack.config.js中挂载) 相比插件不用引进

module: {
   rules: [
     {
       test: /\.css$/,    //正则表达式,匹配对应的后缀文件,然后用底下对应的装载机处理
       use: [ 'style-loader', 'css-loader' ]    //装载顺序为***从右到左***
     }
   ]
}

说明:

  • css-loader:即:编译。加载.css文件,注入到js文件中,以字符串的形式存在
  • style-loader:即:提取。使用<style>将css-loader内部样式注入到我们的HTML页面
  • css-loader/style-loader详细配置点击查看
  • 这种方式在html生成的是<style>标签

方式②:结合extract-text-webpack-plugin插件:实现css分离成文件。这种是<link>样式的方式

安装插件
$ npm install  extract-text-webpack-plugin  --save-dev

使用插件
 引入:
 const ExtractTextPlugin = require('extract-text-webpack-plugin');


//这边对比css-loader/style-loader的区别
module: {
  rules: [
     {
       test: /\.css$/,
       use:ExtractTextPlugin.extract({
         fallback: 'style-loader',    //提取要用到的装载机
         use: [ 'css-loader' ]    //编译要用到的装载机
       })
     }
   ]
}


以及配置plugins:

plugins{
  new ExtractTextPlugin('style.css')  //生成目标css的文件名为style.css
}

说明:

  • 通过extract-text-webpack-plugin插件实现了css的分离,而不是注入js中
  • extract-text-webpack-plugin详细配置点击查看
  • 和webpack4.0+ 不兼容
  • 这种方式在html生成的是<link>标签
  • 所以和第一种方式的优劣势对比即为:<style>和<link>样式的优劣势对比 及css有独立hash等

这边补充对于scss的css文件的处理

安装scss装载机:
$ npm install sass-loader node-sass --save-dev

方式一下使用sass-loader装载机:
module: {
   rules: [
     {
       test: /\.scss$/,    //这边匹配文件后缀为.scss
       use: [ 'style-loader', 'css-loader' ,"sass-loader"]    //只是这边后面增加该装载机
     }
   ]
}

------------------------------------------------------------------
方式二下使用sass-loader装载机:
module: {
  rules: [
     {
       test: /\.scss$/,
       use:ExtractTextPlugin.extract({
         fallback: 'style-loader',    
         use: [ 'css-loader',"sass-loader" ]    
       })
     }
   ]
}


以及配置plugins:

plugins{
  new ExtractTextPlugin('style.css')  
}

其它补充

  • 添加hash: plugins: [new ExtractTextPlugin('style.[hash:5].css')]

七、webpack-dev-server插件的使用

前面有介绍CMD命令包对于全局安装或本地安装的选择,点击回顾
方式①:全局安装 $ npm install webpack-dev-server -g
此时,在CMD即可使用该命令:$ webpack-dev-server //注意此时运行环境为全局的Webpack版本


方式②:项目安装 $ npm install webpack-dev-server --save-dev
此时可以通过配置scripts可以让npm来运行脚本

"scripts": {
  "dev": "webpack-dev-server"
}

此时,可以直接npm run dev来开启本地服务


补充

webpack.config.js中配置

devServer: {
  port: 9000,  //这边配置端口号
  open:true  //这边会自动打开浏览器
},

说明

  • 配置webpack-dev-server 运行时报错配置 Can't resolve 'webpack/hot/dev-server' 。说明项目中,没有安装webpack
  • webpack-dev-server生成的包并没有放在你的真实目录中,而是放在了内存中
  • 和webpack4.0+不兼容,这边webpack@3.8.1安装2.9.1
  • webpack-dev-server的详细配置点击查看
  • 对比webpack --watch避免了打包文件及实现了热更新

八、

# babel6配置过程

九、区分生产环境和开发环境

  • 配置部分区分
  • 方式①:在webpack.json的scripts运行脚本时,增加变量并赋值

eg:"prod": " SET NODE_ENV=production & SET hcl=huchunlin && webpack -p",
配置部分使用:console.log(process.env.NODE_ENV);console.log(process.env.hcl);
说明:process.env.变量来访问
window系统需要SET 。max系统不需要

  • 方式②:不同命令进入,即会执行不同的配置文件

eg:"prod": " webpack -p --config ./config/prod.js",
即通过--config来执行指定配置文件

  • 方式③:相结合
  • 源代码(打包后的文件)区分

通过webpack.DefinePlugin来定义源代码的全局变量。在编译时会进行替换

 webpack.config.js中=>定义全局变量
-----------------------------------------------------------------
 plugins: [
   new webpack.DefinePlugin({
     "hcl": JSON.stringify('这个是在webpack.config定义的变量')
   })
 ]

源代码中,比如在app.js中=>使用全局变量
-----------------------------------------------------------------
 console.log(hcl)
  • 配置文件和源代码都要能区分:结合①和②

  1. 二、全局安装/项目安装

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容