Webpack学习笔记

Webpack

一.认识webpack

  • 什么是webpack?

    • 不是一两句话说得清的
  • 先看看官方解释:

    • At its core, webpack is a static module bundler for modern JavaScript applications.
    • 从本质上来讲,webpack是一个现代的JavaScript应用的静态模块打包工具
  • 我们从两点解释上面这句话

    • 模块打包

    1

    我们通过种种技术开发的应用程序不能直接放到服务器,而是要经过一些工具进行打包,给他做一些转化,生成一些浏览器更容易执行的代码,让浏览器去执行。Webpack就是这样的打包工具。

    还有一些其他的打包工具:grunt/guip/rollup

  • webpack中模块化概念:

    • 在ES6之前,我们想要进行模块化开发,就必须借助于其他的工具,让我们可以进行模块化开发。
    • 并且在通过模块化开发完成了项目后,还需要处理模块间各种依赖,并且将其进行整合打包。
    • 而webpack其中一个核心就是让我们可以进行模块化开发,并且会帮助我们处理模块间的依赖关系。
    • 不仅JavaScript文件,CSS、图片、json文件等在webpack中都可以被当做模块来使用
  • 打包

    • 就是将webpack中的各种资源模块进行打包合并成一个或多个包(Bundle)。
    • 并且在打包过程中,还可以对资源进行处理,比如压缩图片,将scss转成css,将ES6语法转成ES5语法,将TypeScript转成JavaScript等等操作
    • 但打包操作似乎grunt/gulp也可以帮助我们完成,他们有什么不同?
  • webpack和grunt/gulp的对比

    • grunt/gulp的核心是Task
      • 我们可以配置一系列task,并且定义task要处理的事务(例如ES6、ts转化,图片压缩,scss转css)
      • 之后让grunt/gulp来依次执行这些task,而且让整个流程自动化。
      • 所以grunt/gulp也被称为前端自动化任务管理工具
    • 什么情况用grunt/gulp?
      • 工程模块依赖简单,甚至没有模块化概念
      • 只需简单合并压缩
      • 但是如果整个项目使用了模块化管理,而且相互依赖强,我们就使用更加强大的webpack
  • grunt/gulp更加强调前端流程自动化,模块化不是他的核心

  • webpack更加强调模块化开发管理,文件压缩合并预处理是附带功能

二.webpack的安装

  • webpack依赖:webpack依赖Node.js。

  • 全局安装webpack(这里安装3.6.0,vue cli2依赖该版本)

    npm install webpack@3.6.0 -g

  • 局部安装webpack

    • –save-dev 是开发时依赖,项目打包后不需要继续使用的

      1
      2
      cd 对应目录
      npm install webpack@3.6.0 --save-dev
  • 为什么全局安装后,还需局部安装

    • 当在package.json中定义了scripts时,其中包含webpack命令,那么使用的是局部webpack

三.webpack的基本使用过程

打包命令:webpack ./src/main.js ./dist/bundle.js

四.webpack的配置

1.配置package.json和webpack.config.js

  • 将入口和出口放到配置文件:

    • 项目根目录创建webpack.config.js文件

    • 根目录输入node初始化命令:npm init

      • 改个名,main改一下
    • const path=require('path');
      module.exports = {
          entry: './src/main.js',
          output: {
              //拼接绝对路径 
              path: path.resolve(__dirname,'dist'),
              filename: 'bundle.js'
          }
      };
      <!--1-->
    • 映射完打包命令变为:npm run build

    • 优点:优先使用本地webpack

五.loader的使用

什么是loader?

  • loader是webpack中一个非常核心的概念。
  • webpack用来做什么呢?
    • 在上面,我们主要是用webpack来处理js代码,并处理js现关依赖。
    • 但是开发当中我们不仅仅需要有基本的js代码处理,我们也需要处理css、图片、ES6转化ES5等等。
    • 对于webpack本体来说,对于这些转化是不支持的。
    • 我们可以通过给webpack扩展对应的loader来实现这些功能
  • loader使用过程:
    • 步骤一:通过npm安装需要使用的loader
    • 步骤二:在webpack.config.js中的module关键字下进行配置
  • 大部分loader我们都可以在webpack的官网

css文件处理-准备工作

  • style-loadercss-loader

  • 文档链接:https://v4.webpack.docschina.org/loaders/css-loader

  • 安装style-loader:npm install style-loader --save-dev

  • 安装css-loader: npm install --save-dev css-loader

  • webpack.config.js配置:

  • module.exports = {
      module: {
        rules: [
          {
            test: /\.css$/,
              //css-loader只负责将css文件进行加载
              //style-loader负责将样式添加到DOM中
              //使用多个loader时, 是从右向左
            use: ['style-loader','css-loader'],
          },
        ],
      },
    };
    <!--2-->
    

less文件处理-准备工作

  • 安装less-loader:npm install less-loader --save-dev

  • webpack.config.js配置:

  • module.exports = {
      ...
      module: {
        rules: [{
          test: /\.less$/,
          loader: 'less-loader' // 将 Less 编译为 CSS
        }]
      }
    };
    <!--3-->
    

css图片引用处理-准备工作

  • 安装url-loader:npm install url-loader --save-dev

  • webpack.config.js配置:

  • 
    module.exports = {
      entry: './src/main.js',
      output: {
        //拼接绝对路径 
        path: path.resolve(__dirname,'dist'),
        filename: 'bundle.js'
        //css图片引用添加 以后涉及到url 都在url前拼接
        publicPath: 'dist/'
      }
      module: {
        rules: [
          {
            test: /\.(png|jpg|gif)$/i,
            use: [
              {
                loader: 'url-loader',
                options: {
                  limit: 8192
                }
              }
            ]
          }
        ]
      }
    }
    <!--4-->
    

以上仅做记录,实际开发不会这样操作,而是使用vuecli脚手架

ES6语法处理

安装:npm install –save-dev babel-loader@7 babel-core babel-preset-es2015

webpack.config.js配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
module: {
rules: [
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es21015']
}
}
}
]
}

六.webpack中配置Vue

  • 安装vue模块:npm install vue –save
  • 引用:import Vue from ‘vue’
vue运行时有2个版本:
  1. runtime-only:代码中,不可以有任何template
  2. runtime-compliler:代码中,可以有template,因为有compiler编译template
  • 通过修改webpack配置改变版本

    1
    2
    3
    4
    5
    resolve: {
    alias: {
    'vue$': 'vue/dist/vue.esm.js'
    }
    }
真实开发中不会在js文件和index.html文件来回修改
  • 原页面只留<div id="app"></div>

  • app的内容可以放到vue实例的template属性中

  • import Vue from 'vue';
    new Vue({
        el: '#app',
        template: `
        <div>
            <h2>{{message}}</h2>
        <div>
        `,
        data: {
            message: 'hello webpack'
        }
    });
    <!--7-->
  • 抽取到外部文件

  • 新建一个文件app.js

  • export default {
        template: `
        <div>
            <h2>{{message}}</h2>
        <div>
        `,
        data(){
            return {
                message: 'hello webpack'
            }
        }
    }
    <!--8-->
  • 模板和js代码进一步分离

  • 新建App.vue文件

  • <template>
        <div>
            <h2 class="title"><!--15--></h2>
        <div>
    </template>
    
    <script>
        export default {
            name: "App",
            data(){
                return {
                    message: 'hello webpack'
                }
            }
        }
    </script>
    
    <style>
        .title{
            color: red;
        }
    </style>
    
    <!--9-->
  • 此时需要安装vue-loader和vue-template-compiler让webpack能对其进行打包

    从 v14 迁移需要安装插件

  • npm install vue-loader vue-template-compiler --save-dev

  • 修改webpack.config.js配置文件:

    • {
          test: /\.vue$/,
          use: ['vue-loader']
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27

      ### 七.plugin的使用

      - plugin是什么?
      - plugin是插件的意思,通常是用于某个现有的架构进行扩展。
      - webpack中的插件,就是对webpack现有功能的各种扩展,比如打包优化,文件压缩等等。
      - loader和plugin区别
      - loader主要用于转换某些类型的模块,它是一个转换器/加载器。
      - plugin是插件,它是对webpack本身的扩展,是一个扩展器。
      - plugin的使用过程:
      - 步骤一:通过npm安装需要使用的plugins(某些webpack已经内置的插件不需要安装)
      - 步骤二:在webpack.config.js中的plugins中配置插件

      ##### 添加版权Plugin

      修改webpack.config.js文件:

      ```javascript
      const path = require('path');
      const webpack = require('webpack');

      module.exports={
      ...
      plugins: [
      new webpack.BannerPlugin('最终版权归xxx所有')
      ]
      }

然后重新打包即可看到效果

打包html的plugin

  • 目前,我们的index.html文件是存放在项目根目录下的

    • 在真实发布项目时,发布的是dist文件夹中内容,但dist文件夹中如果没有idnex.html文件那就没有意义了
    • 所以我们使用HtmlWebpackPlugin插进将html文件打包到dist文件夹中
  • HtmlWebpackPlugin插件可以为我们做这些事情:

    • 自动生成一个index.html文件(可以指定模板来生成)
    • 将打包的js文件,自动通过script标签插入到body中
  • 安装HtmlWebpackPlugin插件

    • npm install html-webpack-plugin –save-dev
  • 使用插件,修改webpack.config.js文件中plugins部分的内容如下:

    • 这里的template表示根据什么模板来生成index.html

    • 另外,我们需要删除之前在output中添加的publicPath属性

    • 否则插入的script标签src可能会有问题

    • plugins: [
          new htmlWebpackPlugin({
              template: 'index.html'
          }),
      ]
      <!--11-->
  • 查看打包后的js文件,是被压缩过的了

  • ps:现在的新版本webpack只需要把模式改成生产模式,就可以自动压缩了

八.搭建本地服务器

  • webpack提供了一个可选的本地开发服务器,这个本地服务器基于node.js搭建,内部使用express框架,可以实现我们想要的让浏览器自动刷新显示我们修改后的结果

  • 不过它是一个单独的模块,在webpack中使用之前需要先安装它

  • devserver也是作为webpack中的一个选项,选项本身可以设置如下属性:

    • contentBase:为哪一个文件夹提供本地服务,默认是根文件夹,我们这里要填写./dist
    • port:端口号
    • inline:页面实时刷新
    • historyApiFallback:在SPA页面中,依赖HTML5的history模式
  • webpack.config.js文件配置修改如下:

    • devServer: {
          contentBase: './dist',
              inline: true
      },
      <!--12-->
      
      - 然后使用npm run dev
  • 运行指令(不是全局安装使用npx前缀):webpack-dev-server

  • 运行指令:npx webpack-dev-server

九.配置文件的分离

使用插件UglifyjsWebpackPlugin()

评论