Tracy 小笔记 Vue - webpack 打包

webpack

针对 JS 的模块化打包工具

查看当前版本 webpack --version

安装

webpack 的运行需要依赖 node 环境,因此需要先行安装 node 版本要大于 8.9
node 环境为了可以正常的执行很多代码,会包含各种依赖的包 所以安装node 之后会自动会安装 npm (node package manager) 用来管理 node 上面的各种包

全局安装 3.6.0, 因为 vue cil 2 依赖该版本: npm install [email protected] -g
局部安装 : cd 到目录 npm install [email protected] --save--dev

为何全局安装后还要局部安装呢:

  • 在终端执行 webpack 命令时,使用的都是全局安装的 webpack. 如 cmd 终端或者编辑器自带的终端。
  • 在 package.json 文件中定义了 script 时,其中包含了 webpack 命令的话,那么它优先调用的就是局部的 webpack. 局部没有才会调用全局的。 这样在很多人一起做项目的时候只需要用局部的打包,每个人的全局的不一样也不要紧。
  • 一个项目往往是特定版本的 webpack, 都使用全局的话 会导致打包出现问题

打包

src: 源码文件夹 (里面有 js; hbs; cjs; sass; image; json)
dist: 打包文件夹 (distribution 发布)(里面有:css; js; image)

一般 src 文件夹中会由一个入口 js, main.js/index.js
这个js 会调用项目里的各种其他 js. 我们会把所有的 js 打包成一个 bundle.js
cd 到文件夹,webpack 打包命令: webpack ./src/main.js ./dist/bundle.js (这里虽然cd 到文件夹了,其实用的还是全局 webpack)

webpack.config.js 文件配置

  • 可以把上面的"webpack 打包命令"直接简写成 webpack 然后在该配置文件中设置一些东西来实现 webpack ./src/main.js ./dist/bundle.js
  • const path = require('path'); //动态获取绝对路径需要引入的包(webpack 自带)
    
    module.exports = {
      entry : "./src/main.js", //想要打包的主 js 文件, 项目的入口文件
      output: {
         path: path.resolve(__dirname, 'dist'), //动态的获取绝对路径 __dirname 是 npm 的全局变量
         filename: 'bundle.js', //打包之后生成的文件
         publicPath: 'dist/' //文件(如图片)打包之后发送到的文件夹
      },
      module: {
        rules: [
         //配置 各种 loader
        ]
      }
    }
    
  • 执行的时候 直接 cd 到文件夹 执行命令 webpack 即可调用局部 webpack 进行打包工作

package.json 配置

  • 它是 npm init 初始化生成的文件
  • {
      "name": "tracytestvue", //项目名称
      "version": "1.0.0", //项目版本
      "description": "Tracy test vue project", //项目描述
      "main": "webpack.config.js", //以后讲
      "dependencies": { //项目开发时依赖 这里不需要我们自己编辑 npm insert ... 之后会自动添加到这里
        "webpack": "^3.6.0" //说明项目安装了本地 webpack
      },
      "devDependencies": {//项目运行时依赖
      "webpack-bundle-analyzer": "^4.4.0", //分析哪个 js 文件大,影响页面加载速度的
    
      },
      "scripts": { //npm run ... 的映射
        "build": "webpack"// npm run build 时候执行 webpack (这里会调用局部的 webpack),
        "test":"node .build/copy.js" //node 可以抛开浏览器直接执行js 文件,因为服务器没有浏览器, node 的使用使得 js 文件可以成为服务器代码
      },
      "author": "Tracy", //作者
      "license": "ISC"//开源项目的时候才会用的设
    }
    
  • 这个文件里是不能写注释的,写注释后就不能正确执行 npm run build 了

loader 的使用

  • webpack 本身的功能只能支持 js 模块化的打包。 针对于其他文件类型的模块化打包,我们需要给 webpack 下载不同的 loader.
  • loader 涉及的打包领域有: ES6 转 ES5, TypesScript 转换成 ES5, 将 scss/less 转成 css, 将 jsx/vue 文件转成 js 文件
  • loader 的使用过程:
    步骤1: 通过 npm 安装对应的 loader
    步骤2: 在 webpack.config.js 中的 module 关键字下面进行配置
  • loader 官网 (org 结尾的网站一般都是非盈利性质的)
    loader 中文翻译
  • Demo 1 : 将 css 打包进入 bundle.js 文件中
    • 入口 main.js 中写入: import style from './css/common.css'
    • npm install style-loader --save-dev
      npm install --save-dev css-loader
    • webpack.config.js 配置:
      module: {
          rules: [{
            test: /\.css$/,
            use: [
              { loader: "style-loader" }, { loader: "css-loader" }
            ]
          }]
        }
    • 注意: use 数组后面有多个 loader. webpack 是从右向左来读取的, 所以要先写 style-loader 再写 css-loader
      css-loader 只负责将 css 文件进行加载,但是并不会将文件加入到 DOM 中,因此页面不会有样式
      style-loader 负责将样式加入到 DOM 中, 此时页面才开始有样式
    • Tips: 如果打包出错,就查看 package.json 文件 css-loader 和 js-loader 的版本 是不是太高了
      在 package.json 文件手动更改版本为 "css-loader": "^3.3.0", "style-loader": "^1.0.0"
      之后运行 npm install 会自动添加我们手动修改的版本
      再次打包之后错误消失
  • 不同的 loader 都需要写在 rules 中, rules 是一个数组。
  • Demo 2 : 打包 less, scss, sass 的样式文件
    • main.js 引入 less : import less from './css/demo.less'
    • npm install --save-dev less-loader less
    • webpack.config.js 配置:
      {
        test: /\.less$/,
        use: [{ loader: "style-loader" }, { loader: "css-loader" }, { loader: "less-loader" }]
      }
    • less-loader的时候经常会因为版本过高报错, 在 package.json 文件手动更改版本为 4.1.0 之后运行 npm install
  • Demo 3: 打包 image 为 Base64 字符串格式 url-loader 功能类似于 file-loader,但是在文件大小(单位 byte)低于指定的限制时,可以返回一个 DataURL。
    • css 文件中引入 image: background-image: url('../images/view.png');
    • npm install --save-dev url-loader
    • {
        test: /\.(png|jpg|gif|jpeg)$/, //这里我们自己加上 jpeg
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 8192 //当加载的图片小于 limit 的 8kb 的时候会将图片编译成 base64 字符串形式 
              //当图片大于 8kb 的时候需要再下载 file-loader, 这里就不用额外配置什么了
              name: 'images/[name].[hash:8].[ext]' //图片大于 limit file-loader 生成的名字
            }
          }
        ]
      }
    • 图片小于 8kb 打包之后css 文件会变成类似于: background-image:url(data:image/png;base64,iVBORw0KGgoAAAAN...=)
    • 当图片大于 设置的 limit 的 8kb 后会报错, 此时我们需要再配置 npm install --save-dev file-loader
      file-loader : 将文件发送到输出文件夹,并返回(相对)URL
    • webpacl.config 的 output 中需要配置图片要发送过去的文件夹 publicPath: 'dist/'
    • 其他不用再额外配置了,直接 npm run build 即可
      版本过高报错, 在 package.json 文件手动更改版本为 "file-loader": "^4.0.0"
    • 文件会被改名,成为 32位的 hash 哈希值。发送到 publicPath 的文件夹
      但是真实开发中,我们对打包的文件名字是有一定的要求的,此时就要在 option 添加如下选项
      name: 'images/[name].[hash:8].[ext]'
      • images : 文件要打包的文件夹
      • [name] : 获取图片原来的名字
      • [hash:8]: 放置图片名字重复,依然使用 hash, 保留 8位
      • [ext]: 使用原来文件的拓展名
  • Demo 4: ES6 转 ES5
    • npm
    • npm install babel-loader babel-core babel-preset-es2015
      这里先不要按照官网的用 babel-preset-env
    • {
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/, //排除 node_modules 和 bower_components 里的文件
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['es2015']
          }
        }
      }
    • 如果用官网的 babel-preset-env 打包报错后,需要在 webpack.config.js 同级目录创建文件" .babelrc." 然后再进行具体的配置
    • 你必须执行 npm install babel-plugin-transform-runtime --save-dev 来把它包含到你的项目中,也要使用 npm install babel-runtime --save-dev 把 babel-runtime 安装为一个依赖。
  • Demo 5: 打包 .vue 文件
    • npm install vue-loader vue-template-compiler --save-dev
    • webpack.config.js 配置:
      module: {
          rules: [{
            test: /\.vue$/,
            use: [
              { loader: "vue-loader"}
            ]
          }]
        }
    • 此时会报错: vue-loader was used without the corresponding plugin.
      因为 vue loader 版本过高, 可以改成 ^13.0.0 (这个^的意思是会安装 13到14之间的一个合适的版本)
      重新 npm install
    • 引入 vue 文件想从 import App from './vue/App.vue' 变成 import App from './vue/App'
      去掉后缀名: 在 webpack.config.js 文件中的 resolve 中配置
      resolve: {
        extensions:['.js', '.css', '.vue'],
      } 
                      

webpack 中配置 Vue

  • 打包 .vue 文件
  • npm install vue --save (这里不用 --dev 了,因为 vue 不仅是开发时依赖,而且也是运行时依赖)
    默认是安装最新的版本
  • 安装好之后直接引入 import Vue from 'vue';
  • 使用 vue code 进行开发 并打包,此时浏览器 console 会报错
    [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.
  • Vue 不同构件版本: Vue 在 import 的时候会引用两种文件
    • runtime-only: (默认引用) 代码中不可以有任何的 template
    • runtime-compiler: 代码中可以有 template, 因为有 compiler 用于编辑 template
    • template 也就是组件,我们的代码里有根组件,它也是一个组件,所以用 runtime-only 会报错了
  • 解决 runtime-only 报错方案 :
    修改 webpack.config.js, 添加如下属性:
    resolve: {
      alias: {
        'vue$': 'vue/dist/vue.esm.js'
      }
    }

    添加了之后, 在我们 import vue 的时候,就不会默认医用 runtime-only 了, 而是引用 runtime-compiler
  • vue 终极解决方案
    • index.html 文件中

    • main.js 文件
      import style from './css/common.css'
      import less from './css/demo.less'
      
      // vue
      import Vue from 'vue';
      import App from './vue/App'
      
      new Vue({
        el: '#app',
        template: '',
        components: { App }
      });

       

    • App.vue 文件: 正常 vue code

plugin 的使用

  • plugin 是插件,对现有框架的功能进行扩展
  • 使用步骤
    1. 安装: npm *** (某些插件webpack 已经内置因此才不用安装)
    2. 配置: webpack.config.js 中的 plugins :[] 中配置插件
  • Demo: 添加版权声明
    • 安装: 它是 webpack 内置插件所以不用再次安装了
    • 配置 const webpack = require ('webpack');
      plugins :[ new webpack.BannerPlugin('最终版权归 Tracy 所有') ]
  • 打包 html
    目前的 index.html 文件还在 dist 文件夹外面,发布的时候还不是很方便。
    需要将 html 文件打包到 dist 文件夹中发布的时候就拽这个文件夹即可
    • 这个插件为我们做的: 自动生成一个index.html文件(可以指定模板来生成)
      并且将打包好的 js 文件自动通过 script 标签插入到 index.html 的 body 中
    • 安装: npm install html-webpack-plugin --save--div
    • 配置: const htmlWebpackPlugin = require('html-webpack-plugin');
      new htmlWebpackPlugin({template: 'index.html'})
    • 这里的 template 表示根据什么模板来生成 html, 我们目前的 html 是和 webpack.config.js 在同一目录,因此直接写的 index.html 就能找到对应的文件
      另外我们需要删除之前在 out put 之中添加的 publicPath 属性,否则插入的js路径会有问题
    • error : Cannot read property 'make' of undefined
      方法将"html-webpack-plugin"版本由 "^4.2.0"改为 "^3.2.0",
    • 原来 index.html body 中只写
      即可,引入 js 什么的都不用写了
  • 压缩 JS
    • 安装: npm install [email protected] --save-dev
    • 配置: const uglifyjsPlugin = request('uglifyjs-webpack-plugin');
      new uglifyjsPlugin()
    • 此时会发现打包报错:报错是因为最新版的uglifyjs-webpack-plugin插件已经不支持es6语法, 所以已经不适合用这个插件了

搭建本地服务器

  • 可以实现浏览器自动刷新我们改动之后的效果,每次改动后项目会自动打包到内存中
  • 安装: npm install --save-dev [email protected]
  • 在 webpack.config.js 中配置
    devServer:{ contentBase:'./dist', //为哪一个文件夹提供本地 server 服务 port:端口号, //不设置的话就是8080 inline: true, //页面实时刷新 historyApiFallbacl: 在SPA(单页应用)中,依赖 htmk5 的 history 模式,以后细讲 }
  • 在 package.json 中的 "scripts" 里设置 "dev": "webpack-dev-server --open" (这里的open 是指执行时候直接打开浏览器)
  • 启动项目的时候 npm run dev

webpack 配置文件 config.js 的分离

  • 如果把所有的配置都放倒一个 webpack.config.js 文件中,那么在配置很多的时候,是不太合适的.
    有些东西是只在测试环境的时候才需要配置的,比如说“搭建本地服务器”
    有些东西是只在部署环境的时候才需要配置的,比如说丑化js 和 版权管理等
  • 因此我们要把配置文件至少分成三个:
  • base.config.js: 测试和部署环境都会用到的配置
  • dev.config.js: 测试环境配置
  • prod.config.js: 部署环境配置
  • 三个文件都放倒 build 文件夹中
    base.config.js 中的配置就要改了,因为文件夹换了: path: path.resolve(__dirname, '../dist'),
  • 安装 npm install webpack-merge --save-dev 用于在 dev.config.js 文件中将它自己和 base.config.js 合并,执行的时候执行一个 dev.config.js 即可
    在 dev.config.js 和 prod.config.js 中分别配置 :
    const webpackMerge = require('webpack-merge');
    const baseConfig = require('./base.config');
    module.exports = webpackMerge.merge(baseConfig, {里面放 dev.config.js 或者 prod.config.js 里的 code})
  • 删除 webpack.config.js
    在 package.json 文件的 "script"中加上 --config ./build/###.config.js 用于覆盖原来默认的 webpack.config.js 文件的操作
    "build": "webpack --config ./build/prod.config.js",
    "dev": "webpack-dev-server --open --config ./build/dev.config.js"

你可能感兴趣的:(Vue)