webpack 笔记

webpack基础

  • 什么是webpack?
    webpack是前端的一个项目构建工具,它是基于Node.js开发出来的一个前端工具

  • webpack安装

    • 全局安装:npm install webpack -g
    • 安装到项目依赖中(在项目根目录):npm install webpack --save-dev
  • mac安装注意,需要root权限,如果安装不npm成功,可能就是国内网络问题,可以使用代理镜像如:npm config set registry http://registry.npm.taobao.org

  • 浏览器目前解析不了ES6的代码,所以需要使用类似webpack这样的工具来使es6的代码转换成浏览器可以执行的代码

  • webpack 打包

    • webpack ./src/main.js ./dist/bundle.js
    • 命令 打包的文件 打包后存放的目录和名字
  • webpack可以做的事情

    • 能够处理JS文件之间的互相依赖关系
    • webpack能够处理JS的兼容问题,把高级的浏览器不识别的语法转为低级别的浏览器能识别的语法
  • 示例:初步使用webpack隔行渐变功能

  • 安装webpack遇到的问题

    • 直接使用npm install webpack -g命令安装的时候,默认当前用户是没有权限的,需要使用sudo npm install webpack -g或者sudo npm install webpack -g --unsafe-perm=true --allow-root命令获取root权限安装
    • 使用安装的时候会出现在 “node-gyp r” 卡住,需要手动安装node-gyp,建议使用淘宝的npm源,也可以使用cnpm -g install node-gyp进行安装node-gyp,然后重新执行sudo npm install webpack -g命令安装即可成功
    • webpack打包前必须安装webpack-cli,使用npm install webpack-cli -g。注意安装的webpack-cli必须匹配webpack版本,否则也会出现异常。安装webpack-cli加版本号命令如:npm install webpack@3.0.0 -g
  • webpack配置文件的使用

    • 在当前项目根目录,创建webpack.config.js
    • 有了配置文件以后,就可以直接使用webpack命令打包
  • 使用webpack-dev-server来自动实现打包编译的功能

    • 运行npm install webpack-dev-server -D 把这个工具安装到项目的本地开发依赖
    • 安装完毕,这个工具的用法和webpack命令的用法,完全一样
    • 由于我们是在项目中,本地安装的webpack-dev-server,所以无法把它当做脚本命令,在shell终端直接运行;(只有那些安装到全局 -g的功能句,才能在终端中正常执行)
    • 在package.json 中scripts中添加"dev":"webpack-dev-server",然后执行命令:npm run dev。
    • 注意:webpack-dev-server这个工具,如果想要正常运行,要求在本地项目中必须安装webpack,使用命令:npm install webpack -D
    • webpack-dev-server帮我们打包生成的bundle.js文件,并没有存放到实际的物理磁盘上,而是,直接托管到了电脑的内存中,所以我们在项目根目录中,根本找不到这个打包好的bundle.js
    • 我们可以认为webpack-dev-server把打包好的文件,以一种虚拟的形式,托管到了咱们项目的根目录中,虽然我们看不到它,但是可以认为它和dist,src,node_modules平级,有一个看不见的文件叫做bundle.js。在需要引用js的文件的地方引用方式就是/bundle.js
    • webpack命令配置参数一:在package.json 中scripts中添加"dev":"webpack-dev-server --open --port 3000 --contentBase src --hot" 。
    • webpack命令配置参数二:在webpack.config.js中exports下添加:devServer:{
      open: true,//自动打开浏览器
      port: 3000,//设置启动时候运行的端口
      contentBase: 'src', //指定托管的根目录
      hot: true //启用热更新第1步
      }
      const webpack = require('webpack'); // 热更新的第2步
      plugins:[ //配置插件节点
      new webpack.HotModuleReplacementPlugin() //new 一个热更新的模块对象,启用热更新的第三步
      ]
    • 将html页面放入内存中
      1.npm install html-webpack-plugin -D
      2.在webpack.config.js中
      const htmlWebpackPlugin = require('html-webpack-plugin')
      在plugins节点中
      new htmlWebpackPlugin({
      template: path.join(__dirname,'./src/index.html'),//指定模板页面,将来根据指定的路径页面,去生成内存中的页面
      filename: 'index.html' //内存中的页面名称
      })
      3.当使用html-webpack-plugin之后,我们不需要再手动引入bundle.js文件了,因为这个插件已经帮我们自动引入内存中的bundle.js
  • css加载器

    • 注意:webpack默认只打包处理js类型的文件,无法处理其他的非js类型的文件
    • 如果要处理费Js类型的文件,我们需要手动安装一些合适的第三方Loader加载器
    • 如果要打包处理css文件,需要安装cnpm install style-loader css-loader -D
    • 打开webpack.config.js这个配置文件,在里面新增一个配置节点,叫做module,它是一个对象;在这个module对象身上,有一个rules属性,这个rules属性是一个数组,在这个数组中存放了所有第三方文件的匹配和处理规则
    • 在webpack.config.js配置对象代码示例:
       module:{ //这个节点配置所有第三方的加载器
           rules:[
               {test: /\.css$/, use:['style-loader','css-loader']}, // 配置处理.css文件 
              {test: /\.less$/, use: ['style-loader','css-loader','less-loader']}, //配置处理.less文件的第三方loader规则
              {test"/\.cscss$/, use: ['style-loader','css-loader','sass-loader']}, //配置处理.scss文件的第三方loader规则
              {test"/\.(jpg|png|gif|bmp|jpeg)$/, use: 'url-loader?limit=7631&name=[hash:8]-[name].[ext]'}, //配置处理图片路径的第三方loader规则,limit设置图片大小,如果引用的图片小于给定值使用base64编码字符串,否则使用图片路径。
              {test"/\.(ttf|eot|svg|woff|woff2)$/, use: 'url-loader'},// 处理字体文件的loader
           ]
       }
      
    • 在main.js中使用css:
        import 'path/name.css'
    
  • webpack处理第三方文件类型的过程:

    1. 发现这个处理的文件不是JS,然后就去webpack.config.js配置文件中,查找有没有对应的第三方loader规则
    2. 如果找到规则,就会调用对应的Loader处理这种文件类型
    3. 在调用Loader的时候,是从后往前调用的
    4. 当最后一个Loader调用完毕,会把处理的结果,直接交给webpack进行打包合并,最终输出到bundle.js中去
  • 配置处理less文件

    • npm install less -D
    • npm install less-loader -D
  • 配置处理scss文件

    • npm install node-sass -D
    • npm install sass-loader -D
  • 初始化项目:npm init -y 。如果包名含有中文,不能使用-y 。尽量不使用中文的包名

  • 由于webpack是基于Node进行构建的,所以webpack的配置文件中,任何合法的node代码都是支持的

  • webpack中使用url-loader处理字体文件

    • 默认情况下,webpack无法处理css文件中的url地址,不管是图片还是字体库。只要是url地址都处理不了
    • 安装loader: npm install url-loader file-loader -D
    • 使用url-loader处理字体文件
    1. npm install bootstrap -S
    2. 如果要通过路径的形式,去引入node_modules中相关的文件,可以直接省略路径前面的node_modules这一层目录,直接写包的名称,然后后面跟上具体的文件路径
  • webpack中的babel的配置

    • class关键字是ES6中提供的新语法,用来创建ES6中面向对象编程方式。class是从后端语言中借鉴过来实现面向对象
    • static 关键字,可以定义静态属性,可以通过类名直接访问
    • 在webpack中,默认只能处理一部分ES6语法或者ES7语法,一个更高级的语法webpack是处理不了的;这时候,就需要借助第三方loader来帮助webpack处理这些高级的语法,当第三方loader把语法转为低级语法之后,会把结果交给webpack去打包到bundle.js中。
    • 通过Babel可以帮我们将高级语法转换为低级语法。在webpack中,可以运行如下两套命令,安装两套包去安装babel相关的loader功能
    1. 安装第一套包:npm install babel-core babel-loader babel-plugin-transform-runtime -D
    2. 安装第二套包:npm install babel-preset-env babel-preset-stage-0 -D
    3. 打开webpack的配置文件,在module节点下的rules数组中,添加一个新的匹配规则。配置规则时必须把node_modules排除掉:如果不排除,Babel会把node_modules中素有的第三方JS文件,都打包编译,这样会非常消耗CPU,同时打包非常慢。如果不排除,node_module中的js被转换了也无法正常运行:
     {
         test:/\.js$/, use: 'babel-loader', exclude:/node_modules/
     } //转换ES高级语法
    
    1. 在项目目录中,新建一个较重.babelrc的Babel配置文件,这个是json格式文件,内容必须符合JSON语法规范,不能写注释,字符必须使用双引号
    2. .babelrc中配置如下:
         {
             "presets": ["env","stage-0"],
             "plugins":["transform-runtime"]
         }
    
    1. 目前我们安装的babel-preset-env是比较新的ES语法插件,之前安装的是babel-preset-es2015。现在出了一个更新的语法插件babel-preset-env,它包含了所有和es**相关的语法
  • 使用Vue实例的render方法渲染组件

    • 在页面中渲染基本的组件(component)
    • 在页面中使用render函数渲染组件
  • 在普通网页中使用vue

    • 使用script标签,引入vue包
    • 在index页面中,创建一个id为app的div容器
    • 通过new vue 得到一个vm的实例
  • 在webpack中使用vue

    • 安装包vue包:npm install vue -S
    • 使用vue示例代码:
  import Vue from 'vue' // 这个引入方式无法正常执行
  import Vue from '../node_modules/vue/dist/vue.js' //这种引入方式可以正常执行
  import login from './login.vue' // 导入vue模板

  var vm = new Vue({
      el: '#app', //指定容器,需要在页面中顶一个id为app的div
      data: {
          msg: '123'
      },
      components:{ //在webpack中无法使用组件方式,展示vue模板
          login
      },
      render: function(createElements){ // 在webpack 中,如果想通过vue,把一个组件放到页面中去展示,vm 实例中的render函数可以实现
          return createElements(login)
      }

      render: c => c(login) //render简写
  })
  • 注意:在webpack中,使用import Vue from 'vue'都的Vue构造函数,功能不完整,只提供了runtime-only的方式并没有提供像网页中那样的使用方式。解决这个问题,可以使用两种方式:
  1. 修改导入包:import Vue from '../node_modules/vue/dist/vue.js'
  2. 不修改导入包(推荐),在webpack.config.js中添加新的模块
 resolve: {
     alias:{
         "vue$": "vue/dist/vue.js", //修改vue被导入时候的包的路径
     }
 }
  • .vue文件定义组件模板对象内容:
    • html内容在<template></template>中
    • js业务逻辑在<sccript></sccript>中
    • 样式内容在<style></style>中
  • 使用webpack处理.vue文件,需要在webpack.config.js中配置加载插件,否则无法解析.vue文件中的内容
    • 添加加载插件:const VueLoaderPlugin = require('vue-loader/lib/plugin');
    • 在plugins添加定义的插件:new VueLoaderPlugin()
  • webpack如果要打包处理.vue文件,需要一些操作:
    • 需要安装相关的loader: npm install vue-loader vue-template-compiler -D
    • 在配置文件中,新增loader配置项:{test:/.vue$/, use: 'vue-loader'}
  • 向外暴露成员的方式
    • node中向外暴露成员的方式:module.exports = {},使用require导入
    • ES6中:使用export default和export向外暴露成员,使用import导入
    • export default {},可以使用任意变量来接收。而且在同一个js文件中只能使用一次export default来暴露成员变量
    • 在一个js文件中可以同时使用export default和export暴露成员变量
    • 使用export向外暴露的成员,只能使用{}的形式接收,这种形式叫做按需导出。
    • export可以向外宝暴露多个成员,同时如果某些成员,我们在import的时候不需要,则可以不在{}中定义
    • 使用export导出的成员,必须严格按照导出时的名称在{}按需导入
    • 使用export导出的成员,如果就想换个名称来接收,可以使用as来启别名
  • 结合webpack使用vue-router
    • 安装vue-router: npm install vue-router
    • 导入vue-router: import VueRouter from 'vue-router'
    • 手动安装vueRouter: Vue.use(VueRouter)
    • 使用:
      var router = new VueRouter({
          routes: [
              //acount goodslist
              { path: '/account',component: account }
              { path: '/goodslist',component: goodslist }
          ]
      })
    
      var vm = new Vue({
          el: '#app',
          render: c => c(app), //render会把el中指定的容器中的内容都清空,所以不要把router-view和router-link直接填写到el中
          router //将路由挂载到vm上
      })
    
      //html中使用组件
    
      <div id="app">
          <router-link to="/account">Account</router-link>
          <router-link to="/goodslist">goodslist</router-link>
    
          <router-view></router-view>
      </div>
    
    • app这个组件是通过VM实例的render函数,render函数如果需要渲染组件,渲染出来的组件,只能放到el:'#app'所指定的元素中
    • Account和Goodslist组件,是通过路由匹配监听到的,所以这两个组件,只能展示到属于路由的<router-view></router-view>中去
  • 结合webpack实现children子路由(路由嵌套)
    • vsCode安装vue插件Vetur和 Vue 2 Snippets
      import login 'sub/login.vue'
      import login 'sub/register.vue'
    
      var router = new VueRouter({
          routes: [
              //acount goodslist
              { path: '/account',component: account,
                  children: [
                      {path: 'login',component: login},
                      {path: 'register',component: register}
                  ]
               },
              { path: '/goodslist',component: goodslist }
          ]
      })
    
  • 组件中style标签属性和scoped属性的介绍
    • 使用
      <style scoped>
          div {
              color:red
          }
      </style>
    
    • 普通的style标签只支持普通的样式,如果要启用scss或less需要为style元素设置lang属性
      <style lang="scss" scoped>
          body {
              div{
                  color: red
              }
          }
      </style>
    
    • 只要咱们的style标签,是在.vue组件中定义的,那么推荐都为style开启scoped属性
  • webpack路由嵌套
    • 创建router.js。将所有路由相关js都移动到这个文件中统一管理
    • 在router.js中添加: export default router
    • 导入路由 import router from './router.js'
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,254评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,875评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,682评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,896评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,015评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,152评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,208评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,962评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,388评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,700评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,867评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,551评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,186评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,901评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,689评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,757评论 2 351