webpack介绍使用配置教程详解

目录
  • 一、webpack介绍
  • 1、由来
  • 2、介绍
  • 3、作用
  • 4、拓展说明
  • 5、webpack整体认知
  • 二、webpack安装
  • 1、安装node
  • 2、安装cnpm
  • 3、安装nrm的两种方法
  • 4、安装webpack
  • 三、webpack配置
  • 0、搭建项目结构
  • 1、初始化一个项目(会创建一个package.json文件)
  • 2、在当前的项目中安装Webpack作为依赖包
  • 3、当前项目结构
  • 4、实现CSS打包
  • 5、实现SCSS打包
  • 6、实现Less打包
  • 7、实现打包url资源(图片、gif、图标等)功能
  • 8、Webpack-dev-server结合后端服务器的热替换配置
  • 9、ES6转换为ES5语法
  • 10、防止文件缓存(生成带有20位的hash值的唯一文件)
  • 11、抽取CSS为单独文件
  • 12、开发环境和生产环境的分离
  • 13、在生产环境中配置代码压缩功能
  • 四、webpack1和webpack2的区别

webpack介绍和使用

一、webpack介绍

1、由来

由于前端之前js、css、图片文件需要单独进行压缩和打包,这样团队人员处理很繁琐,然后 Instagram 团队就想让这些工作自动化,然后webpack应运而生。

2、介绍

webpack是一个模块打包器(module bundler),webpack视HTML,JS,CSS,图片等文件都是一种 资源 ,每个资源文件都是一个模块(module)文件,webpack就是根据每个模块文件之间的依赖关系将所有的模块打包(bundle)起来。

3、作用

  • 对 CommonJS 、 AMD 、ES6的语法做了兼容
  • 对js、css、图片等资源文件都支持打包(适合团队化开发)
  • 比方你写一个js文件,另外一个人也写一个js文件,需要合并很麻烦,现在交给webpack合并很简单
  • 有独立的配置文件webpack.config.js
  • 可以将代码切割成不同的chunk,实现按需加载,降低了初始化时间
  • 具有强大的Plugin(插件)接口,大多是内部插件,使用起来比较灵活
  • ……

4、拓展说明

  • CommonJS、AMD、CMD是用于JavaScript模块管理的三大规范,CommonJS定义的是模块的同步加载,是一个更偏向于服务器端的规范(也可以在浏览器中使用),主要用于Nodejs,根据CommonJS规范,一个单独的文件就是一个模块,加载模块使用require()方法,该方法读取一个文件并执行,最后返回文件内部的exports对象。
  • AMD和CMD则是定义模块异步加载适用于浏览器端,都是为了 JavaScript 的模块化开发,(这里说一下为什要有异步加载,因为浏览器如果使用common.js同步加载模块的话,就会导致性能等问题,所以针对这个问题,又出了一个规范,这个规范可以实现异步加载依赖模块)
    • AMD规范会提前加载依赖模块,AMD规范是通过requireJs 在推广过程中对模块定义的规范化产出。(AMD 规范:https://github.com/amdjs/amdjs-api/wiki/AMD
    • CMD规范会延迟加载依赖模块, CMD 规范是 SeaJs 在推广过程中对模块定义的规范化产出。

      (CMD规范:https://github.com/seajs/seajs/issues/242

    • AMD规范和CMD规范的区别
      • 对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。不过 RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)
      • CMD 推崇依赖就近,AMD 推崇依赖前置
      • AMD 的 API 默认是一个当多个用,CMD 的 API 严格区分,推崇职责单一。比如 AMD 里,require 分全局 require 和局部 require,都叫 require。CMD 里,没有全局 require,而是根据模块系统的完备性,提供 seajs.use 来实现模块系统的加载启动。CMD 里,每个 API 都简单纯粹
    • webpack和gulp的区别
      • gulp是前端自动化构建工具,强调的是前端开发的工作流程,我们可以通过配置一系列的task,定义task处理的事情(代码压缩、合并、编译、浏览器实时更新等),然后定义执行顺序,来让gulp执行这些task,从而构建项目的整个前端开发流程,自动化构建工具并不能把所有模块打包到一起,也不能构建不同模块之间的依赖关系。
      • webpack是 JavaScript 应用程序的模块打包器,强调的是一个前端模块化方案,更侧重模块打包,我们可以把开发中的所有资源(图片、js文件、css文件等)都看成模块,通过loader(加载器)和plugins(插件)对资源进行处理,打包成符合生产环境部署的前端资源。

5、webpack整体认知

​ (1)、webpack的核心概念分为 入口(Entry)、加载器(Loader)、插件(Plugins)、出口(Output);

webpack整体认知

  • 入口(Entry):入口起点告诉 webpack 从哪里开始,并根据依赖关系图确定需要打包的文件内容
  • 加载器(Loader):webpack 将所有的资源(css, js, image 等)都看做模块,但是 webpack 能处理的只是 JavaScript,因此,需要存在一个能将其他资源转换为模块,让 webpack 能将其加入依赖树中的东西,它就是 loader。loader用于对模块的源代码进行转换。loader 可以使你在 import 或"加载"模块时预处理文件。因此,loader 类似于其他构建工具中“任务(task)”,并提供了处理前端构建步骤的强大方法。
    • rules: [
          {
              test: /\.(js|jsx)$/,
              use: 'babel-loader'
          }
      ]
      
  • 插件(Plugins):loader 只能针对某种特定类型的文件进行处理,而 plugin 的功能则更为强大。在 plugin 中能够介入到整个 webpack 编译的生命周期,Plugins用于解决 loader 无法实现的其他事情,也就是说loader是预处理文件,那plugin 就是后处理文件。
    • 对loader打包后的模块文件(bundle.js)进行二次优化处理,例如:代码压缩从而减小文件体积
    • 提供辅助开发的作用:例如:热更新(浏览器实时显示)
    • plugins: [
          new webpack.optimize.UglifyJsPlugin(),
          new HtmlWebpackPlugin({template: './src/index.html'})
      ]
      

二、webpack安装

1、安装node

使用 node -v 命令检查版本

2、安装cnpm

https://cnpmjs.org/

npm install -g cnpm --registry=https://registry.npm.taobao.org

使用 cnpm -v 命令检查版本

3、安装nrm的两种方法

https://www.npmjs.com/package/nrm

nrm可以帮助我们切换不同的NPM源的快捷开关,可以切换的NPM源包括:npmcnpmtaobaorednpmnpmMirroredunpm

  • 第一种方法(由于是外网访问进行安装,可能会被墙)
    npm install -g nrm
    
  • 第二种方法(国内的淘宝镜像,访问稳定,推荐)
    cnpm install -g nrm
    

    使用 nrm - V 命令检查版本(注意这里的 V 是大写的)

    • 使用nrm ls 命令可以查看当前可以可以切换的 NPM源
    • 使用 npm use cnpm 命令 指定要使用的哪种NPM源

4、安装webpack

  • 全局安装

    • npm install --global webpack
      
  • 在项目中安装最新版本或特定版本,分别执行以下命令:
    • npm install --save-dev webpack
      npm install --save-dev webpack@<version>
      

三、webpack配置

0、搭建项目结构

webpack(项目总目录)

  • dist
  • src
    • js

      • moudle1.js

        • function sum(x,y){
              return x + y;
          }
          // 导出 sum 函数
          module.exports = sum;
          
      • main.js
        • // 1、获取index.html中的dom对象
          
          var first = document.getElementById('first');
          var btn = document.getElementById('btn');
          var two = document.getElementById('two');
          var res = document.getElementById('res');
          btn.onclick = function(){
                          var firstValue = parseFloat(first.value);
                          var twoValue = parseFloat(two.value);
                          //2、获取 module1.js中的 sum函数
                          //http://www.ruanyifeng.com/blog/2015/05/require.html
                          var sum = require('./module1.js');
                          res.value = sum(firstValue,twoValue);
                      }
          
  • index.html

    • <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Document</title>
      </head>
      
      <body>
          <input type="text" id="first">
          <input type="button" id="btn" value="+">
          <input type="text" id="two">
          <input type="button" id="btn" value="=">
          <input type="text" id="res">
          <script src="./dist/js/bulid.js"></script>
      </body>
      </html>
      
  • webpack.config.js(手动创建)
    • const path = require('path');  // 首先要引入node.js中path 模块,用于处理文件与目录的路径
      
      // const 命令声明一个只读的常量,一旦声明,值不可以改变,改变会报错;只声明不赋值也会报错
      // 常量存储的是一个不可以变化的变量。
      //
      module.exports = {
          entry:'./src/./js/main.js', // 指定入口文件
          output:{
              path: path.resolve(__dirname, './dist/js'), // 指定出口文件的路径目录
              filename: 'bulid.js' // 制定出口文件的名称
          },
      

1、初始化一个项目(会创建一个package.json文件)

npm init

2、在当前的项目中安装Webpack作为依赖包

npm install --save-dev webpack

说明:--save :将配置信息保存到package.json中,

同时 --save :也是项目生产环境,项目发布之后还依赖的东西,保存在dependencies

例如:如果你用了 jQuery,由于发布之后还是依赖jQuery,所以是dependencies

--save-dev :是项目开发环境依赖的东西,保存在devDependencies中

例如:写 ES6 代码,如果你想编译成 ES5 发布那么 babel 就是devDependencies

3、当前项目结构

当前项目结构

4、实现CSS打包

  • npm install css-loader style-loader --save-dev
    或者
    cnpm install css-loader style-loader --save-dev
    
  • 在src—>css目录中新建main.css

    • #first{
          border: 1px solid red;
      }
      
  • 在webpack.config.js中配置相关的loader
    • const path = require('path');  // 首先要引入node.js中path 模块,用于处理文件与目录的路径
      
      // const 命令声明一个只读的常量,一旦声明,值不可以改变,改变会报错;只声明不赋值也会报错
      // 常量存储的是一个不可以变化的变量。
      //
      module.exports = {
          entry:'./src/./js/main.js', // 指定入口文件
          output:{
              path: path.resolve(__dirname, './dist/js'), // 指定出口文件的路径目录
              filename: 'bulid.js' // 制定出口文件的名称
          },
          module:{
              rules:[
              // 在webpack2中,loaders 被替换成了 rules 其实就是loader的规则
                  {
                      test: /\.css$/,
                      use: [ 'style-loader', 'css-loader' ]
                      // test 说明了当前 loader 能处理那些类型的文件
                      // use 则指定了 loader 的类型。
                      // 注意:数组中的loader不能省略扩展名
                  }
              ]
          }
      }
      
  • 在main.js中获取css目录中的main.css文件
    • // 1、获取index.html中的dom对象
      var first = document.getElementById('first');
      var btn = document.getElementById('btn');
      var two = document.getElementById('two');
      var res = document.getElementById('res');
          btn.onclick = function(){
              var firstValue = parseFloat(first.value);
              var twoValue = parseFloat(two.value);
              //2、获取 module1.js中的 sum函数
              //http://www.ruanyifeng.com/blog/2015/05/require.html
              var sum = require('./module1.js');
              res.value = sum(firstValue,twoValue);
          }
      
          // 3、获取css目录中的main.css文件
          require('../css/main.css');
      
  • 在终端中输入 webpack命令进行css文件打包

5、实现SCSS打包

  • 在src目录中新建 sass目录--> scss1.scss

    • // scss1.scss文件
      $color:purple;
      #two{
          border:1px solid $color;
      }
      
  • 安装对应的loader
    • npm install sass-loader node-sass webpack --save-dev
      
    • 或者
    • cnpm install sass-loader css-loader style-loader node-sass webpack --save-dev
      
  • 在webpack.config.js中配置相关的loader
  •    const path = require('path');  // 首先要引入node.js中path 模块,用于处理文件与目录的路径
    
       // const 命令声明一个只读的常量,一旦声明,值不可以改变,改变会报错;只声明不赋值也会报错
       // 常量存储的是一个不可以变化的变量。
       //
       module.exports = {
           entry:'./src/./js/main.js', // 指定入口文件
           output:{
               path: path.resolve(__dirname, './dist/js'), // 指定出口文件的路径目录
               filename: 'bulid.js' // 制定出口文件的名称
           },
           module:{
               rules:[
               // 在webpack2中,loaders 被替换成了 rules 其实就是loader的规则
               //  实现 css 打包
                   {
                       test: /\.css$/,
                       use: [ 'style-loader', 'css-loader' ]
                       // test 说明了当前 loader 能处理那些类型的文件
                       // use 则指定了 loader 的类型。
                       // 注意:数组中的loader不能省略扩展名
                   },
                   {
                       test: /\.scss$/,
                       // 注意 是sass-loader ,不是 scss-loader
                       use: [ 'style-loader', 'css-loader', 'sass-loader' ]
                   }
    
               ]
           }
       }
    
  • 在js目录中 main.js里面引入 scss1.scss
    • // 1、获取index.html中的dom对象
      
      var first = document.getElementById('first');
      var btn = document.getElementById('btn');
      var two = document.getElementById('two');
      var res = document.getElementById('res');
      
      btn.onclick = function(){
          var firstValue = parseFloat(first.value);
          var twoValue = parseFloat(two.value);
          //2、获取 module1.js中的 sum函数
          //http://www.ruanyifeng.com/blog/2015/05/require.html
          var sum = require('./module1.js');
          res.value = sum(firstValue,twoValue);
      }
      
      // 3、获取css目录中的main.css文件
      require('../css/main.css');
      
      // 4、获取sass目录中的scss1.scss文件
      require('../sass/scss1.scss');
      
  • 在终端中输入 webpack命令进行scss文件打包

6、实现Less打包

  • 安装

    • cnpm install --save-dev
      
    • cnpm install less less-loder css-loader style-loader  webpack --save-dev
      
    • 或者
    • cnpm install less-loader less --save-dev在webpack.config.js中配置相关的loader
      
  • 在在src目录中新建less目录--> less1.less
  • @color:blue;
    #res{
        border:1px dashed blue;
    }
    
  • 在webpack.config.js中配置相关的loader
    • const path = require('path');  // 首先要引入node.js中path 模块,用于处理文件与目录的路径
      
      // const 命令声明一个只读的常量,一旦声明,值不可以改变,改变会报错;只声明不赋值也会报错
      // 常量存储的是一个不可以变化的变量。
      //
      module.exports = {
          entry:'./src/./js/main.js', // 指定入口文件
          output:{
              path: path.resolve(__dirname, './dist/js'), // 指定出口文件的路径目录
              filename: 'bulid.js' // 制定出口文件的名称
          },
          module:{
              rules:[
              // 在webpack2中,loaders 被替换成了 rules 其实就是loader的规则
                  //  实现 css 打包
                  {
                      test: /\.css$/,
                      use: [ 'style-loader', 'css-loader' ]
                      // test 说明了当前 loader 能处理那些类型的文件
                      // use 则指定了 loader 的类型。
                      // 注意:数组中的loader不能省略扩展名
                  },
                  // 实现 scss 打包
                  {
                      test: /\.scss$/,
                      // 注意 是sass-loader ,不是 scss-loader
                      use: [ 'style-loader', 'css-loader', 'sass-loader' ]
                  },
                  // 实现 less 打包
                  {
                      test: /\.less$/,
                      use: [ 'style-loader', 'css-loader', 'less-loader' ]
                  }
      
              ]
          }
      }
      
  • 在js目录中 main.js里面引入 less1.less文件
    • // 5、获取less目录中的less1.less文件
      require('../less/less1.less');
      

7、实现打包url资源(图片、gif、图标等)功能

  • 在src 目录中 新建imgs目录,放入两张不同大小的图片
  • 在index.html中新增 <div id="bg1"></div> <div id="bg2"></div>
  • 在mian.css中新增
    • // mian.css文件
      #bg1{
          width: 200px;
          height: 200px;
          background: url('../imgs/bxg.jpg');
      }
      
      #bg2{
          width: 200px;
          height: 200px;
          background: url('../imgs/web.jpg') no-repeat;
      }
      
  • 前言

    如果我们希望在页面引入图片(包括img的src和background的url)。当我们基于webpack进行开发时,引入图片会遇到一些问题。

    ​ 其中一个就是引用路径的问题。拿background样式用url引入背景图来说,我们都知道,webpack最终会将各个模块打包成一个文件,因此我们样式中的url路径是相对入口html页面的,而不是相对于原始css文件所在的路径的。这就会导致图片引入失败。这个问题是用file-loader解决的,file-loader可以解析项目中的url引入(不仅限于css),根据我们的配置,将图片拷贝到相应的路径,再根据我们的配置,修改打包后文件引用路径,使之指向正确的文件。

    ​ 另外,如果图片较多,会发很多http请求,会降低页面性能。这个问题可以通过url-loader解决。url-loader会将引入的图片编码,生成dataURl。相当于把图片数据翻译成一串字符。再把这串字符打包到文件中,最终只需要引入这个文件就能访问图片了。当然,如果图片较大,编码会消耗性能。因此url-loader提供了一个limit参数,小于limit字节的文件会被转为DataURl,大于limit的还会使用file-loader进行copy。

    ​ url-loader和file-loader是什么关系呢?简答地说,url-loader封装了file-loader。url-loader不依赖于file-loader,即使用url-loader时,只需要安装url-loader即可,不需要安装file-loader,因为url-loader内置了file-loader。通过上面的介绍,我们可以看到,url-loader工作分两种情况:1.文件大小小于limit参数,url-loader将会把文件转为DataURL;2.文件大小大于limit,url-loader会调用file-loader进行处理,参数也会直接传给file-loader。因此我们只需要安装url-loader即可。

  • 安装
    • cnpm install
      
    • cnpm install url-loader file-loader --save-dev
      
  • 在webpack.config.js中配置相关的loader
    • const path = require('path');  // 首先要引入node.js中path 模块,用于处理文件与目录的路径
      
      // const 命令声明一个只读的常量,一旦声明,值不可以改变,改变会报错;只声明不赋值也会报错
      // 常量存储的是一个不可以变化的变量。
      //
      module.exports = {
          entry:'./src/./js/main.js', // 指定入口文件
          output:{
              path: path.resolve(__dirname, './dist/js'), // 指定出口文件的路径目录
              filename: 'bulid.js' // 制定出口文件的名称
              publicPath:'dist/'
              // path:所有输出文件的目标路径;
              // publicPath:输出解析文件的目录,url 相对于 HTML 页面
          },
          module:{
              rules:[
              // 在webpack2中,loaders 被替换成了 rules 其实就是loader的规则
                  //  实现 css 打包
                  {
                      test: /\.css$/,
                      use: [ 'style-loader', 'css-loader' ]
                      // test 说明了当前 loader 能处理那些类型的文件
                      // use 则指定了 loader 的类型。
                      // 注意:数组中的loader不能省略扩展名
                  },
                  // 实现 scss 打包
                  {
                      test: /\.scss$/,
                      // 注意 是sass-loader ,不是 scss-loader
                      use: [ 'style-loader', 'css-loader', 'sass-loader' ]
                  },
                  // 实现 less 打包
                  {
                      test: /\.less$/,
                      use: [ 'style-loader', 'css-loader', 'less-loader' ]
                  },
                  // 实现 url 资源打包
                  {
                      // 图片和字体文件使用 url-loader 来处理
                      test: /\.(png|jpg|gif|ttf|eot|woff|woff2|svg)$/,
                      use: [
                          {
                              loader: 'url-loader',
                              // options 为可以配置的选项
                              options: {
                                  limit: 8192
                                  // limit=8192表示将所有小于8kb的图片都转为base64形式(为什么                               呢?因为一个很小的图片,不值当的去发送一个请求,减少请求次                               数。)
                                  // (其实应该说超过8kb的才使用 url-loader 来映射到文件,否                              则转为dataurl形式)
                              }
                          }
                    ]
                     //保证输出的图片名称与之前命名的图片名称保持一致(目前只是支持这样的写法,                   webpack3 没有响应的options进行配置)
                   // use:'url-loader?limit=8192&amp;name=imgs/[name].[ext]'
                }
      
                ]
            }
        }
      
  • 在main.js中引入mui目录中icons-extra.css的文件
    • // 5、获取less目录中的less1.less文件
      require('../less/less1.less');
      
      // 6、获取src目录中的mui目录中icons-extra.css的文件
      require('../mui/css/icons-extra.css');
      

8、Webpack-dev-server结合后端服务器的热替换配置

webpack-dev-server提供了一个简单的 web 服务器,并且能够实时重新加载(live reloading),同时把生成好的js和html构建到我们的电脑内存中,这样的话,即使我们的目录中没有了相关js等文件,还能够加载出来,这样能够提高我们页面运行速度。

  • 安装 webpack-dev-server 插件

    • // 先把之前依赖的包安装
      cnpm install
      
    • cnpm install webpack-dev-server --save-dev
      
    •  // webpack.config.js
         const path = require('path');  // 首先要引入node.js中path 模块,用于处理文件与目录的路径
         // const 命令声明一个只读的常量,一旦声明,值不可以改变,改变会报错;只声明不赋值也会报错
         // 常量存储的是一个不可以变化的变量。
         module.exports = {
             entry:'./src/./js/main.js', // 指定入口文件
             output:{
                 path: path.resolve(__dirname, 'dist/js'), // 指定出口文件的路径目录
                 filename: 'bulid.js' // 制定出口文件的名称
             },
             module:{
                 rules:[
                 // 在webpack2中,loaders 被替换成了 rules 其实就是loader的规则
                     //  实现 css 打包
                     {
                         test: /\.css$/,
                         use: [ 'style-loader', 'css-loader' ]
                         // test 说明了当前 loader 能处理那些类型的文件
                         // use 则指定了 loader 的类型。
                         // 注意:数组中的loader不能省略扩展名
                     },
                     // 实现 scss 打包
                     {
                         test: /\.scss$/,
                         // 注意 是sass-loader ,不是 scss-loader
                         use: [ 'style-loader', 'css-loader', 'sass-loader' ]
                     },
                     // 实现 less 打包
                     {
                         test: /\.less$/,
                         use: [ 'style-loader', 'css-loader', 'less-loader' ]
                     },
                     // 实现 url 资源打包
                     {
                         // 图片文件使用 url-loader 来处理
                         test: /\.(png|jpg|gif|ttf)$/,
                         use: [
                         {
                             loader: 'url-loader',
                             // options 为可以配置的选项
                             options: {
                               limit: 8192
                               // limit=8192表示将所有小于8kb的图片都转为base64形式
                               // (其实应该说超过8kb的才使用 url-loader 来映射到文件,否则转为data url形式)
                           }
                       }
                       ]
                   }
      
                   ]
               },
                devServer: {
                 // contentBase: './dist', // 在 localhost:8080(默认) 下建立服务,将 dist 目录下的文件,作为可访问文件  contentBase:告诉服务器从哪里提供内容
                 // 或者通过以下方式配置
                 contentBase: path.join(__dirname, "dist"),
                 compress: true,
                 // 当它被设置为true的时候对所有的服务器资源采用gzip压缩
                 // 对JS,CSS资源的压缩率很高,可以极大得提高文件传输的速率,从而提升web性能
                 port: 9000, // 如果想要改端口,可以通过 port更改
                 hot: true, // 启用 webpack 的模块热替换特性()
                 inline: true, // 实现实时重载(实现自动刷新功能)默认情况下是 true。
                 host: "localhost" // 如果你希望服务器外部可访问,指定使用一个 host。默认是 localhost(也就是你可以不写这个host这个配置属性)。
             }
          }
      
    // package.json
       {
         "name": "mywebpack",
         "version": "1.0.0",
         "description": "",
         "main": "webpack.config.js",
         "scripts": {
           "test": "echo \"Error: no test specified\" &amp;&amp; exit 1",
           "start": "webpack-dev-server --open"
           // "start": "webpack-dev-server --open --port 8080 --hot --inline"  // 如果在这里配置了,就不用在webpack.config.js中配置devServer属性了。
         },
         "author": "",
         "license": "ISC",
         "devDependencies": {
           "css-loader": "^0.28.7",
           "file-loader": "^1.1.5",
           "html-webpack-plugin": "^2.30.1",
           "less": "^3.0.0-alpha.3",
           "less-loader": "^4.0.5",
           "node-sass": "^4.5.3",
           "sass-loader": "^6.0.6",
           "style-loader": "^0.19.0",
           "url-loader": "^0.6.2",
           "webpack": "^3.8.1",
           "webpack-dev-server": "^2.9.3"
         }
       }
    
       ```
    
    -   在命令行中运行 `npm start`,就会看到浏览器自动加载页面。如果现在修改和保存任意源文件,web 服务器就会自动重新加载编译后的代码,但是打开后发现,打开的是 dist目录,我们想要的是 index.html显示我们的页面,所以这是我们还要借助里另一个 `html-webpack-plugin` 插件。
    
  • html-webpack-plugin 简单创建 HTML 文件,用于服务器访问,其中包括使用script标签的body中的所有webpack包。
  • 安装 html-webpack-plugin 插件
    • cnpm install --save-dev html-webpack-plugin
      
  • webpack.config.js配置
  • const path = require('path'); // 首先要引入node.js中path 模块,用于处理文件与目录的路径
    // const 命令声明一个只读的常量,一旦声明,值不可以改变,改变会报错;只声明不赋值也会报错
    // 常量存储的是一个不可以变化的变量。
    
    // 引入html-webpack-plugin 插件
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    
    const webpack = require('webpack');
    module.exports = {
        entry: './src/./js/main.js', // 指定入口文件
        output: {
            path: path.resolve(__dirname, 'dist/js'), // 指定出口文件的路径目录
            filename: 'bulid.js' // 制定出口文件的名称
        },
        module: {
            rules: [
                // 在webpack2中,loaders 被替换成了 rules 其实就是loader的规则
                //  实现 css 打包
                {
                    test: /\.css$/,
                    use: ['style-loader', 'css-loader']
                        // test 说明了当前 loader 能处理那些类型的文件
                        // use 则指定了 loader 的类型。
                        // 注意:数组中的loader不能省略扩展名
                },
                // 实现 scss 打包
                {
                    test: /\.scss$/,
                    // 注意 是sass-loader ,不是 scss-loader
                    use: ['style-loader', 'css-loader', 'sass-loader']
                },
                // 实现 less 打包
                {
                    test: /\.less$/,
                    use: ['style-loader', 'css-loader', 'less-loader']
                },
                // 实现 url 资源打包
                {
                    // 图片文件使用 url-loader 来处理
                    test: /\.(png|jpg|gif|ttf)$/,
                    use: [{
                        loader: 'url-loader',
                        // options 为可以配置的选项
                        options: {
                            limit: 8192
                                // limit=8192表示将所有小于8kb的图片都转为base64形式
                                // (其实应该说超过8kb的才使用 url-loader 来映射到文件,否则转为data url形式)
                        }
                    }]
                }
    
            ]
        },
        devServer: {
            // contentBase: './dist', // 在 localhost:8080(默认) 下建立服务,将 dist 目录下的文件,作为可访问文件  contentBase:告诉服务器从哪里提供内容
            // 或者通过以下方式配置
            contentBase: path.join(__dirname, "dist"),
            port: 9000, // 如果想要改端口,可以通过 port更改
            hot: true, // 启用 webpack 的模块热替换特性()
            inline: true, // 实现实时重载(实现自动刷新功能)默认情况下是 true。
            host: "localhost" // 如果你希望服务器外部可访问,指定使用一个 host。默认是 localhost(也就是你可以不写这个host这个配置属性)。
        },
        plugins: [
            new HtmlWebpackPlugin({
                title: '首页', // 用于生成的HTML文档的标题
                filename: 'index.html', //写入HTML的文件。默认为index.html。也可以指定一个子目录(例如:)assets/admin.html
                template: 'index.html' // Webpack需要模板的路径
            }),
            new webpack.HotModuleReplacementPlugin() // 需要结合 启用热替换模块(Hot Module Replacement),也被称为 HMR
        ]
    }
    
  • 再次使用npm start命令就可以实现浏览器自动更新。
  • 问题来了,HtmlWebpackPlugin中的 title并没有显示出来,原因是需要在定义的template模板中使用ejs语法,
    • &lt;!DOCTYPE html&gt;
      &lt;html lang="en"&gt;
      &lt;head&gt;
          &lt;meta charset="UTF-8"&gt;
          &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
           &lt;!-- EJS 语法
                  /* EJS是一个简单高效的模板语言,通过数据和模板,可以生成HTML标记文本。可以说EJS是一个JavaScript库,EJS可以同时运行在客户端和服务器端,客户端安装直接引入文件即可 */
              --&gt;
          &lt;title&gt;&lt;%= htmlWebpackPlugin.options.title%&gt;&lt;/title&gt;
      &lt;/head&gt;
      
      &lt;body&gt;
          &lt;input type="text" id="first"&gt;
          &lt;input type="button" id="btn" value="+"&gt;
          &lt;input type="text" id="two"&gt;
          &lt;input type="button" id="btn" value="="&gt;
          &lt;input type="text" id="res"&gt;
          &lt;div id="bg1"&gt;&lt;/div&gt;
          &lt;div id="bg2"&gt;&lt;/div&gt;
      &lt;/body&gt;
      &lt;/html&gt;
      
  • 再次使用npm start命令就可以啦。

9、ES6转换为ES5语法

  • 安装

    • cnpm install --save-dev babel-loader babel-core babel-preset-env
      
      • babel-core如果某些代码需要调用Babel的API进行转码,就要使用babel-core模块
      • babel-preset-env通过根据您的目标浏览器或运行时环境自动确定您需要的Babel插件
    • babel 对一些公共方法使用了非常小的辅助代码,比如 _extend。 默认情况下会被添加到每一个需要它的文件中,你可以引入 babel runtime 作为一个独立模块,来避免重复引入。
      • 你必须执行 npm install babel-plugin-transform-runtime --save-dev 来把它包含到你的项目中,也要使用 npm install babel-runtime --savebabel-runtime 安装为一个依赖
  • 配置
// 实现 url 资源打包
                    {
                        // 图片文件使用 url-loader 来处理
                        test: /\.(png|jpg|gif|ttf)$/,
                        use: [{
                            loader: 'url-loader',
                            // options 为可以配置的选项
                            options: {
                                limit: 8192
                                    // limit=8192表示将所有小于8kb的图片都转为base64形式
                                    // (其实应该说超过8kb的才使用 url-loader 来映射到文件,否则转为data url形式)
                            }
                        }]
                    },
                    // 实现 ES6转 ES5
                    {
                        test: /\.js$/,
                        exclude: /(node_modules)/,  // exclude 排除的意思,把 node_modules文件夹排除编译之外
                        use: {
                            loader: 'babel-loader',
                            options: {
                            // presets 预设列表(一组插件)加载和使用
                            presets: ['env'],
                            plugins: ['transform-runtime'] // 加载和使用的插件列表
                            }
                        }
                    }
  • 把一些代码改成ES6 语法的写法

    • // moudule1.js
      
      function sum(x,y){
          return x + y;
      }
      // 导出 sum 函数
      // module.exports = sum;
          // 改成ES6 的写法语法
      export default{
          sum
      }
      
    -   ```js
        // main.js
    
        // 1、获取index.html中的dom对象
        var first = document.getElementById('first');
        var btn1 = document.getElementById('btn1');
        var two = document.getElementById('two');
        var res = document.getElementById('res');
        console.log(1);
        btn1.onclick = function() {
            var firstValue = parseFloat(first.value);
            var twoValue = parseFloat(two.value);
            //2、获取 module1.js中的 sum函数
            //http://www.ruanyifeng.com/blog/2015/05/require.html
            console.log(2);
    
            /* var sum = require('./module1.js');
             res.value = sum(firstValue,twoValue);*/
            res.value = sumObj.sum(firstValue, twoValue);
        }
    
        // 3、获取css目录中的main.css文件
        // require('../css/main.css');
    
        //  把步骤3 改为 ES6写法,引入css目录中的main.css文件
        import '../css/main.css';
    
        // 4、获取sass目录中的scss1.scss文件
        require('../sass/scss1.scss');
    
        // 5、获取less目录中的less1.less文件
        require('../less/less1.less');
    
        // 6、获取src目录中的mui目录中icons-extra.css的文件
        require('../mui/css/icons-extra.css');
    
        // 把 var sum = require('./module1.js'); 写成 ES6语法
        import sumObj from './module1.js'
        ```
    

10、防止文件缓存(生成带有20位的hash值的唯一文件)

  • // webpack.config.js
    
    output: {
            path: path.resolve(__dirname, 'dist/js'), // 指定出口文件的路径目录
            // filename: 'bulid.js' // 制定出口文件的名称
            filename: '[name].[hash].js' // 将入口文件重命名为带有20位的hash值的唯一文件
        }
    

11、抽取CSS为单独文件

  • 安装插件从 build.js文件中提取文本(CSS)到单独的文件

    • npm install --save-dev extract-text-webpack-plugin
      
  • 在webpack.config.js中配置
    • const path = require('path'); // 首先要引入node.js中path 模块,用于处理文件与目录的路径
      // const 命令声明一个只读的常量,一旦声明,值不可以改变,改变会报错;只声明不赋值也会报错
      // 常量存储的是一个不可以变化的变量。
      
      // 引入html-webpack-plugin 插件
      const HtmlWebpackPlugin = require('html-webpack-plugin');
      
      const webpack = require('webpack');
      
      const ExtractTextPlugin = require("extract-text-webpack-plugin");
      
      module.exports = {
          entry: './src/./js/main.js', // 指定入口文件
          output: {
              path: path.resolve(__dirname, 'dist'), // 指定出口文件的路径目录
              // filename: 'bulid.js' // 制定出口文件的名称
              // path指定了本地构建地址,publicPath指定在浏览器中所引用的,指定的是构建后在html里的路径
              // publicPath: './',
              // 将入口文件重命名为带有20位的hash值的唯一文件
              filename: '[name].[hash].js'
          },
          module: {
              rules: [
                  // 在webpack2中,loaders 被替换成了 rules 其实就是loader的规则
                  //  实现 css 打包
                  /*{
                      test: /\.css$/,
                      use: ['style-loader', 'css-loader']
                          // test 说明了当前 loader 能处理那些类型的文件
                          // use 则指定了 loader 的类型。
                          // 注意:数组中的loader不能省略扩展名
                  },*/
                  // 实现 scss 打包
                  {
                      test: /\.scss$/,
                      // 注意 是sass-loader ,不是 scss-loader
                      use: ['style-loader', 'css-loader', 'sass-loader']
                  },
                  // 实现 less 打包
                  {
                      test: /\.less$/,
                      use: ['style-loader', 'css-loader', 'less-loader']
                  },
                  // 实现 url 资源打包
                  {
                      // 图片文件使用 url-loader 来处理
                      test: /\.(png|jpg|gif|ttf)$/,
                      use: [{
                          loader: 'url-loader',
                          // options 为可以配置的选项
                          options: {
                              limit: 8192
                                  // limit=8192表示将所有小于8kb的图片都转为base64形式
                                  // (其实应该说超过8kb的才使用 url-loader 来映射到文件,否则转为data url形式)
                          }
                      }]
                     //保证输出的图片名称与之前命名的图片名称保持一致(目前只是支持这样的写法,                   webpack3 没有响应的options进行配置)
                      // use:'url-loader?limit=8192&amp;name=imgs/[name].[ext]'
                  },
                  // 实现 ES6转 ES5
                  {
                      test: /\.js$/,
                      exclude: /(node_modules)/, // exclude 排除的意思,把 node_modules文件夹排除编译之外
                      use: {
                          loader: 'babel-loader',
                          options: {
                              // presets 预设列表(一组插件)加载和使用
                              presets: ['env'],
                              plugins: ['transform-runtime'] // 加载和使用的插件列表
                          }
                      }
                  },
                  // 提取 css模块(如果使用这个模块的话,需要把之前的CSS打包模块注释掉,不然会重复)
                  {
                      test: /\.css$/,
                      use: ExtractTextPlugin.extract({
                          fallback: "style-loader",
                          use: "css-loader"
                      })
                  }
      
              ]
          },
          devServer: {
              // contentBase: './dist', // 在 localhost:8080(默认) 下建立服务,将 dist 目录下的文件,作为可访问文件  contentBase:告诉服务器从哪里提供内容
              // 或者通过以下方式配置
              contentBase: path.join(__dirname, "dist"),
              port: 9000, // 如果想要改端口,可以通过 port更改
              hot: true, // 启用 webpack 的模块热替换特性()
              inline: true, // 实现实时重载(实现自动刷新功能)默认情况下是 true。
              host: "localhost" // 如果你希望服务器外部可访问,指定使用一个 host。默认是 localhost(也就是你可以不写这个host这个配置属性)。
          },
          plugins: [
              // 从 bundle 中提取文本(CSS)到单独的文件
              new ExtractTextPlugin({
                  //  提取css,并重名为带有 20位的hash值的唯一文件
                  filename: '[name].[hash].css',
                  // 将所有的独立文件模块(这里指的是css文件)合并成一个文件
                  allChunks: true
              }),
              new HtmlWebpackPlugin({
                  title: '首页', // 用于生成的HTML文档的标题
                  filename: 'index.html', //写入HTML的文件。默认为index.html。也可以指定一个子目录(例如:)assets/admin.html
                  template: 'index.html' // Webpack需要模板的路径
                      // template: 'index.ejs' // Webpack需要模板的路径
              }),
              // 需要结合webpack-dev-server 启用热替换模块(Hot Module Replacement),也被称为 HMR
              new webpack.HotModuleReplacementPlugin()
          ]
      }
      

12、开发环境和生产环境的分离

(1)开发环境与生产环境分离的原因如下:

  • 在开发环境中,我们使用热更新插件帮助我们实现浏览器的自动更新功能,我们的代码没有进行压缩,如果压缩了不方便我们调试代码等等,所以以上这些代码不应出现在生产环境中。
  • 生产环境中,我们把项目部署到服务器时,我们会对代码进行各种各样的优化,比如压缩代码等等,这时候我们不应该把这些代码放到开发环境中,不利于代码开发和调试。

总结:针对以上这些说明,我们很有必要把区分开发环境与生产环境分离。

(2)开发环境的配置和生产换环境配置的区别。

  • 开发环境有的配置,生产环境不一定有,比如说热更新时使用到的HotModuleReplacementPlugin
  • 生产环境有的配置,开发环境不一定有,比如说用来压缩js用的UglifyJsPlugin
  • 如何去做?

    • 1> 因为webpack 默认找的是 webpack.config.js配置文件,所以要把开发环境的webpack.config.js配置文件改为webpack.dev.config.js代表开发环境的配置文件。
    • 2> 新建一个webpack.prod.config.js,再把开发环境中的webpack.config.js复制进去(没用的配置文件该删除的删除
    • 3> 修改package.json文件(在scripts 标签中添加"dev""prod" 属性配置)
      •  "scripts": {
                "test": "echo \"Error: no test specified\" &amp;&amp; exit 1",
                "dev": "webpack --config webpack.dev.config.js",
                "prod": "webpack --config webpack.prod.config.js"
            },
        

怎样执行命令

  • 执行开发环境的中配置

    • npm run dev
  • 执行生产环境的中配置
    • npm run prod

13、在生产环境中配置代码压缩功能

  • 配置webpack.prod.config.js 文件

    • // webpack.prod.config.js
      
      var UglifyJsPlugin = webpack.optimize.UglifyJsPlugin;
      
       // ……
      
         plugins: [
      
             // ……
      
              // js代码 压缩
              new UglifyJsPlugin({
                  compress: {
                      warnings: false
                  }
              })
          ]
      
  • 执行 npm run prod 命令

四、webpack1和webpack2的区别

webpack1.0已经废弃使用,建议使用webpack2.0+

1、resolve.modulesDirectories 被重命名为 resolve.modules

2、module.loaders 将继续支持,但在未来它将被module.rules 替换。

以上就是webpack介绍使用配置教程详解的详细内容,更多关于webpack使用配置的资料请关注我们其它相关文章!

(0)

相关推荐

  • webpack教程之webpack.config.js配置文件

    首先我们需要安装一个webpack插件html-webpack-plugin,该插件的作用是帮助我们生成创建html入口文件.执行如下命令 npm install html-webpack-plugin --save-dev 在项目app目录下建立component.js文件,写入如下代码 export default (text='hello world')=>{ const element=document.createElement('div'); element.innerHTML=te

  • Vue + Webpack + Vue-loader学习教程之相关配置篇

    前言 之前已经介绍过了Vue + Webpack + Vue-loader的相关功能介绍,大家可以点击这篇文章了解详情.下面就来看看相关配置篇,感兴趣的可以参考学习. 使用预处理器 在 Webpack 中,所有的预处理器需要和一个相应的加载器一同使用.vue-loader 允许你用其它的 Webpack 加载器去处理 Vue 组件一部分代码.它会根据 lang 属性自动用适当的加载器去处理. CSS 例如,我们编译用 SASS 编译 <style> 标签: npm install sass-l

  • webpack构建vue项目的详细教程(配置篇)

    最近公司要求用vue重构项目,还涉及到模块化开发,于是乎,我专门花了几天的时间研究了一下webpack这个目前来看比较热门的模块加载兼打包工具,发现上手并不是很容易,现将总结的一些有关配置的心得分享出来,欢迎大神来拍砖... 一.新建一个项目目录,cd /d 定位进去,然后输入npm init,会提示你填写一些项目的信息,一直回车默认就好了,或者直接执行npm init -y 直接跳过,这样就在项目目录下生成了一个package.json文件. 二.接下来就是通过npm安装项目依赖项,命令行输入

  • Vue+webpack项目配置便于维护的目录结构教程详解

    新建项目的时候创建合理的目录结构便于后期的维护是很重要 环境:vue.webpack 目录结构: 项目子目录结构 子目录结构都差不多,主要目录是在src下面操作 src目录结构 src/common 目录 主要用来存放公共的文件 src/components 主要用来存放公共的组件 src/config 用来存放配置文件,文件目录如下 src/config/index.js 配置目录入口文件 import api from './website' // 当前平台 export const HOS

  • Vue+webpack项目基础配置教程

    最近在学习webpack,跟着课程一个单页面应用,在这里记录一下.这个部分主要讲了如何配置webpack的环境,以及webpack dev的配置. 记录比较粗略,后续会更新. 1.开发环境:vscode,node.js,vue.js,webpack 大家自己安装一下node.js可以参考菜鸟教程 使用的IDE是 VScode 2.项目初始化 快捷键ctrl+` 打开vscode控制台 vscode界面 2.1安装webpack vue vue-loader npm init npm i webp

  • 使用webpack3.0配置webpack-dev-server教程

    最近正在研究webpack,听说webpack可以自己搭建一个小型的服务器(使用过vue-cli的朋友应该都见识到过),所以迫不及待的想要尝试一下.不过,在实际操作中发现,用webpack搭建服务器仍有不少坑,一方面是由于自己对文档的不熟悉,不了解webpack-dev-server的运作模式:另一方面,在翻阅了不少博客和文章后,发现不少配置实际上都跑不起来(有可能是版本的原因,也有可能是我自己配置的原因).所以我打算用webpack3.0把dev-server跑起来给大家演示一遍,顺便把一些配

  • webpack介绍使用配置教程详解

    目录 一.webpack介绍 1.由来 2.介绍 3.作用 4.拓展说明 5.webpack整体认知 二.webpack安装 1.安装node 2.安装cnpm 3.安装nrm的两种方法 4.安装webpack 三.webpack配置 0.搭建项目结构 1.初始化一个项目(会创建一个package.json文件) 2.在当前的项目中安装Webpack作为依赖包 3.当前项目结构 4.实现CSS打包 5.实现SCSS打包 6.实现Less打包 7.实现打包url资源(图片.gif.图标等)功能 8

  • vue-cli3中vue.config.js配置教程详解

    前言 vue-cli3推崇零配置,其图形化项目管理也很高大上. 但是vue-cli3推崇零配置的话,导致了跟之前vue-cli2的配置方式都不一样了. 别名设置,sourcemap控制,输入文件位置和输出文件位置和输出的方式,压缩js控制,打包webapck日志分析,externals忽略配置(外部引入),调试的端口配置,proxy接口配置等等的. 有时候还需要我们配置的,因为官方推荐的,并不适用于我们平时的开发所用的. 所以,我的vue.config.js配置是下面这样的.还有一个改hash的

  • Linux 下FTP的安装与配置教程详解

    0.安装ftp的前置条件是关掉SElinux # vi /etc/selinux/config 修改 SELINUX=" disabled " ,重启服务器.若相同,则跳过此步骤. 1. 可先查看是否安装过vsftp # rpm -qa | grep vsftpd 则代表已经安装.可直接跳过步骤2 2 .安装 vsftp # yum install vsftp* Is this ok [y/N]: y 代表安装完成. 3. 对vsftp 进行配置 # /etc/vsftpd/vsftp

  • CentOS7+apache+php7+mysql5.7配置教程详解

    yum upgrade yum install net-tools 安装apache 关闭SELinux 编辑器打开 etc/selinux/config 文件,找到 SELINUX=enforcing 字段,将其改成 SELINUX=disabled ,并重启设备. yum -y install httpd mod_ssl 配置防火墙 firewall-cmd --permanent --add-port=80/tcp firewall-cmd --permanent --add-port=4

  • Mybatis 创建方法、全局配置教程详解

    总体介绍:MyBatis实际上是Ibatis3.0版本以后的持久化层框架[也就是和数据库打交道的框架]! 和数据库打交道的技术有: 原生的JDBC技术--->Spring的JdbcTemplate技术 这些工具都是提供简单的SQL语句的执行,但是和我们这里学的MyBatis框架还有些不同, 框架是一整套的东西,例如事务控制,查询缓存,字段映射等等. 我们用原生JDBC操作数据库的时候都会经过: 编写sql---->预编译---->设置参数----->执行sql------->

  • MySQL5.6.31 winx64.zip 安装配置教程详解

    #1. 下载 # #2.解压到本地 修改必要配置my*.ini #3.mysql install admin模式启动cmd cd mysql目录/bin 执行安装: mysqld -install 启动mysql服务: net start mysql 关闭mysql服务: net stop mysql #4.mysql 编码配置 <解压版MySQL-5.6.31-winx64 编码配置> 在根目录下面有已经写好的"my-"开头的ini文件,如:my-default.ini.

  • CentOS安装mysql5.7 及简单配置教程详解

    安装 保证你的用户有权限 安装 没有 切换 root su root (su的意思:swich user) # rpm -ivh http://dev.mysql.com/get/mysql57-community-release-el6-9.noarch.rpm 可能会遇到 warning: /var/tmp/rpm-tmp.6V5aFC: Header V3 DSA/SHA1 Signature, key ID 5072e1f5: NOKEY 可以忽略(个人意见,百度了一下没找到合适的答案)

  • MySql 5.7.17免安装配置教程详解

    1.下载mysql-5.7.17-winx64.zip安装包(链接:https://dev.mysql.com/downloads/mysql/) 2.解压安装包. D:\DevelopTool\mysql-5.7.17-winx64   #解压目录 3.在解压目录下创建一个名为data的文件夹,用来存放数据 D:\DevelopTool\mysql-5.7.17-winx64\data 4.配置启动文件 把 D:\DevelopTool\mysql-5.7.17-winx64\my-defau

  • centOS7下Spark安装配置教程详解

    环境说明: 操作系统: centos7 64位 3台         centos7-1 192.168.190.130 master         centos7-2 192.168.190.129 slave1         centos7-3 192.168.190.131 slave2 安装spark需要同时安装如下内容: jdk  scale 1.安装jdk,配置jdk环境变量 这里不讲如何安装配置jdk,自行百度. 2.安装scala 下载scala安装包,https://www

  • Linux中selinux基础配置教程详解

    selinux(Security-Enhanced Linux)安全增强型linux,是一个Linux内核模块,也是Linux的一个安全子系统. 三种模式: Enforcing:强制模式,在selinux运作时,已经开始限制domain/type. permissive: 警告模式,在selinux运作时,会有警告讯息,但不会限制domain/type的存取. disabled: 关闭模式. 可用getenforce查看selinux状态 selinux对文件的作用: 当开启selinux后,s

随机推荐