webpack3.0笔记

1.了解Webpack

  • 什么是webpack
    • webpack是一个模块打包器(bundler)
    • 在webpack看来,前端的所有资源文件(js/json/css/img/less/...)都会作为模块处理
    • 它会根据模块的依赖关系进行静态分析,生成对应的静态资源
  • 四个核心概念
    • Entry:入口起点(entry point)指示webpack应该使用哪个模块,来作为构建其内部依赖图的开始
    • Output:告诉webpack在哪里输出它所创建的bundles,以及如何命名这些文件,默认值为 ./dist
    • Loader:loader可以让webpack能够去处理那些非JavaScript文件(webpack自身只能解析:JavaScript、json)
    • plugins:插件可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量等
  • 理解Loader
    • webpack本身只能加载js/json模块,如果要加载其他类型的文件(模块),就需要使用对应的loader进行转换/加载
    • 它本身是一个函数,接受源文件作为参数,返回转换的结果
    • loader一般以xxx-loader的方式命名,xxx代表了这个loader要做的转换功能,比如json-loader
  • 理解插件plugin
    • 插件可以完成一些loader不能完成的功能
    • 插件的使用一般是在webpack的配置信息plugins选项中指定
    • CleanWebpackPlugin:自动清除指定文件夹资源
    • HtmlWebpackPlugin:自动生成HTML文件
    • UglifyJSPlugin:压缩js文件
  • 配置文件(默认)
    • webpack.config.js:是一个node模块,返回一个json格式的配置信息对象


2.学习文档

  • webpack官网:http://webpack.github.io/
  • webpack3文档(英文):https://webpack.js.org/
  • webpack3文档(中文):https://doc.webpack-china.org/

3.webpack的基本使用

1.生成package.json文件
2.安装webpack(都要安装):
    - npm install webpack@3 -g //全局安装
    - npm install webpack@3 --save-dev //局部安装
3.小试牛刀处理一个js
    执行命令:webpack src/js/index.js  build/index.js
观察发现webpack会把es6语法,直接编译为浏览器识别的模块化语法,不过类似于箭头函数等依然存在

4.使用webpack配置文件

webpack的核心文件:执行webpack命令时,会在当前目录查找webpack.config.js文件读取配置
1.通过commonjs暴露出去一个对象
2.四个关键的概念:
    entry:入口文件,将所有打包资源全部引入
    output:输出,将资源输出到指定目录下
    loader:处理webpack不能够解析的模块
    plugins:执行loader做不了的任务
3.如何找到自己想要的loader?
    优先去官网找自己想要的loader,没有再去npm官网上找
4.在终端输入:webpack ./src/js/app.js ./build/js/build.js
    问题:这种方式只能够编译打包js、json文件,其他文件处理不了
5.webpack --display-modules可以查看隐藏的任务
const path = require('path') //path内置的模块,用来设置路径

module.exports = {
  //入口(从哪里进入开始解析)
  entry:'./src/js/index.js',
  
  //出口(最终加工完的代码输出到哪里)
  output: {// 输出配置
    path: path.resolve(__dirname, 'build'),//输出文件路径配置
    filename: 'index.js',//输出文件名
  }
}

5.在package.json中配置npm命令

"scripts":{
   "build":"webpack"
}
//打包应用运行:npm run build

6.使用loader解析less文件(使用less-loader)

1.安装:npm install less-loader less --save-D
2.安装:npm install css-loader style-loader --save-D
3.向rules中写入配置:
  {
    test: /\.less$/,
    use: [
      {
        loader: "style-loader" //创建一个style标签,将js中的css放入其中
      },
      {
        loader: "css-loader" //将css以commonJs语法打包到js中
      },
      {
        loader: "less-loader" //将less转换成css
      }
    ]
  }
4.在入口js中引入less文件:import '../less/demo.less'

7.file-loader处理图片资源

1.安装:npm install --save-dev file-loader
2.新增loader:
  {
    test: /\.(png|jpg|gif)$/,
    use: [
      {
        loader: 'file-loader', //如果不做图片转base64,可以用file-loader
        options: {
          outputPath: 'img', //图片最终输出的位置
          publicPath: '../build/img', //css资源图片路径
          name: '[hash:5].[ext]' //修改图片名称
        }
      }
    ]
  }

8.url-loader处理图片资源&base64

1.安装:npm install url-loader --save-D
2.修改loader为:
  {
    test: /\.(png|jpg|gif)$/,
    use: [
      {
        loader: 'url-loader', // 如果不做图片转base64,可以用file-loader
        options: {
          limit: 8192,
          outputPath: 'img', // 图片最终输出的位置
          publicPath: '../build/img', // css资源图片路径
          name: '[hash:5].[ext]' // 修改图片名称
        }
      }
    ]
  }
  3.备注:一定要注意路径的问题

9.使用插件提取css,合并为单独的文件

1.安装ExtractTextWebpackPlugin插件:npm install extract-text-webpack-plugin --save-D
2.引入插件:const ExtractTextPlugin = require("extract-text-webpack-plugin")
3.新增plugins插件配置项,并实例化ExtractTextPlugin插件:
  plugins: [
    //提取css为单独文件
    new ExtractTextPlugin("./css/index.css")
  ]
4.修改原less-loader的配置如下:
  {
    test: /\.less$/, //匹配文件的规则,说明该loader对哪个文件生效
    use: ExtractTextPlugin.extract({
      fallback: "style-loader",
      use: ["css-loader", "less-loader"]
    })
  }
5.备注:因为css提取成单独文件,不再包含在js中了,所以要修改url-loader配置publicPath为: '../img'

10.js语法检查

1.安装jshint-loader:npm i jshint-loader --save -D
2.新增loader:
  {
    test: /\.js$/, //涵盖.js文件
    enforce: "pre", //预先加载jshint-loader
    exclude: /node_modules/, //排除掉 node_modules 文件夹下的所有文件
    use: [
      {
        loader: "jshint-loader",
        options: {
          //jshint的错误信息默认情况下会显示为warning(警告)类信息
          //将emitErrors参数设置为true可使错误显示为error(错误)类信息
          emitErrors: false,
          //jshint默认情况下不会打断webpack编译
          //如果你想在jshint出现错误时,立刻停止编译
          //请设置 failOnHint 参数为true
          failOnHint: false
        }
      }
    ]
  }
3.备注:有一个小坑,就是仅仅安装jshint-loader还不够,
  还要安装js-hint,命令:npm i jshint --save -D

11.es6转es5

1.安装babel-loader,命令:npm install babel-loader babel-core babel-preset-es2015 --save -D
2.配置新的loader
  {
    test: /\.js$/,
    exclude: /(node_modules|bower_components)/,
    use: {
      loader: 'babel-loader',
      options: {
        persets: ['es2015']
      }
    }
  }
3.坑!提示找不到"@babel/core",根据提示执行:npm i babel-loader@7 --save -D

12.html文件的处理和清除文件夹

1.对于html的操作,虽然有了html-loader这个loader,不过功能有限我们的需求是:
想让webpack自动的帮我们创建一个html,然后把我们想要引入的东西引入进来,所以要借助插件。
2.使用插件HtmlWebpackPlugin,安装:npm install --save-dev html-webpack-plugin
3.引入插件:const HtmlWebpackPlugin = require('html-webpack-plugin')
4.新增一个插件配置项:
  new HtmlWebpackPlugin({
    title: 'webpack',
    filename:'index.html',
    template:'./src/index.html'
  })
  备注:要在html模板中写入<%= htmlWebpackPlugin.options.title %>,title配置才生效
5.删除掉模板html中的所有引入
6.为了清空工作目录,安装插件:clean-webpack-plugin,命令:npm i clean-webpack-plugin -D
7.引入插件:const {CleanWebpackPlugin} = require('clean-webpack-plugin')
8.实例一个插件:
    new CleanWebpackPlugin('./build')
备注:最新版的CleanWebpackPlugin不传任何参数

13.提取build环境配置文件

1.新建文件目录:config
2.移动webpack.config.js文件到config中,改名为:webpack.build.js
3.通过执行:webpack --display-modules --config ./config/webpack.build.js 指定配置文件运行
4.完善一下:在package.json中定义命令:
      "build": "webpack --display-modules --config ./config/webpack.build.js"
5.以后可以通过:npm run build代替完整命令
6.【问题】:发现build文件夹出现在了config中,解决办法如下:
    修改出口output中的path为:resolve(__dirname, '../build')
7.【问题】:上一步的清空位置发生了改变,解决办法如下:
    修改CleanWebpackPlugin插件的配置如下:
      new CleanWebpackPlugin('./build', {
        root:resolve(__dirname,'../')
      })
备注:如果使用的clean-webpack-plugin插件是2.0以上的,则不会出现问题7

14.提取dev环境配置文件(dev环境搭建)

1.复制一份webpack.build.js,改名为:webpack.dev.js
2.安装dev-server:npm i webpack-dev-server@2 -D(下载第2个版本,3版本有兼容性问题)
3.修改package.json的配置:"dev": "webpack-dev-server --config ./config/webpack.dev.js"
4.在webpack.dev.js中配置dev服务器编:
    //配置开发服务器
    devServer: {
      hot: true,//热模替换
      open: true,//自动打开浏览器
      port: 3001,
      compress: true//启用gzip压缩
    }    
  备注:官网-->配置-->开发中server(devserver)可见详细配置
5.启用HMR(热模替换)
     引入webpack:const webpack = require("webpack")
      追加一个插件:new webpack.HotModuleReplacementPlugin()
6.存在的问题:改了css、html还得手动刷新才可以,解决如下:
7.【解决css无法模块热更新的问题】因为css用的是插件,不是loader,所以不行,解决办法:重新使用loader的方式
8.【解决html无法自动刷新的问题】因为html也是插件,办法:html依然用插件,追加使用loader,安装:npm i html-loader -D 
    新增html-loader配置项如下
  {
    test: /\.(html)$/,
    use: {
      loader: 'html-loader'
    }
  }
同时entry重写为:['./src/js/index.js','./src/index.html']
备注:需要注意的是:dev方式的运行是加载在内存中的,没有任何输出

15.提取公共代码实现复用

1.参考webpack.build.js,新增:webpack.common.js
2.webpack.common.js中删除所有css的loader,删除CleanWebpackPlugin,删除ExtractTextPlugin插件,删除最上方二者的引用
3.在webpack.build.js上方引入:const common = require('./webpack.common')
4.安装合并库:npm i webpack-merge -D,引入merge库:const merge = require('webpack-merge')
5.module.exports = merge(common,{当前文件所有配置})
6.剔除webpack.build.js中:入口,出口,图片处理,js语法检查,es6转换,HtmoWebpackPlugin
7.剔除webpack.dev.js中:出口,图片处理,js语法检查,es6转换,插件只保留:HotModuleReplacementPlugin

16.prod环境配置

复制webpack.build.js。改名:webpack.prod.js
package.json中追加:"prod": "webpack --display-modules --config ./config/webpack.prop.js"
pro模式输出的文件在dist文件夹中,修改出口配置:path:resolve(__dirname, '../dist'),filename: './js/[name].[hash:10].js'
修改css插件配置:new ExtractTextPlugin("./css/[name].[hash:10].css")

【压缩js】
使用插件(用于压缩js文件):UglifyjsWebpackPlugin
引入webpack:const webpack = require('webpack')
插件中新增配置:new webpack.optimize.UglifyJsPlugin({sourceMap:true})
追加一个配置(与插件同级):devtool:'source-map'

【css扩展前缀】
使用loader:postcss-loader,执行安装:npm i -D postcss-loader
在css的loader配置中加入postcss-loader:use: ["css-loader","postcss-loader","less-loader"]
在根目录新建postcss.config.js文件,配置如下内容:
  module.exports = {
    "plugins": {
        "autoprefixer": {
          "browsers": [
            "ie >= 8",
            "ff >= 30",
            "chrome >= 34",
            "safari >= 7",
            "opera >= 23"
          ]
        }
    }
  }
安装所需的autoprefixer,命令:npm i autoprefixer -D

【压缩css】
使用less-plugin-clean-css插件,命令:npm i less-plugin-clean-css -D
引入插件:const CleanCSSPlugin = require("less-plugin-clean-css")
替换use中的less-loader为对象,如下:
  loader: "less-loader",options: {
    plugins: [
      new CleanCSSPlugin({ advanced: true })  
    ]
  }

【压缩html】
将webpack.common.js中的HtmlWebpackPlugin插件复制过来
追加一个配置项:minify:{ removeComments:true, collapseWhitespace:true }

webpack面试题

1.webpack的核心概念

Entry:入口,webpack进行打包的起始点(文件)
Output:出口,webpack编译打包生成的bundle(打包文件)
Loader:模块加载(转换)器,将非js、非json模块包装成webpack能理解的js模块
Plugin:插件,在webpack构建流程中的特定时机插入具有特定功能的代码
Module:模块,在webpack眼中一起皆模块,默认只识别js文件,如果是其他类型文件利用对应的loader转换为js模块

2.webpack配置文件的整体结构

module.exports = {
  entry: '', //入口
  output: {}, //输出
  module: {rules: []}, //配置loader
  plugins: [] //配置plugin
}

3.webpack模块化打包的基本流程

1.连接:webpack从入口js开始,递归查找出所有相关联的模块,并【连接】起来形成一个图(网)的结构
2.编译:将js模块中的模块化语法【编译】为浏览器可以直接运行的模块语法(当然其他类型资源也会处理)
3.合并:将图中所有编译过的模块【合并】成一个或少量的几个bundle文件,浏览器真正运行是打包生成的bundle文件

4.比较loader与plugin

1.loader:用于加载特定类型的资源文件,webpack本身只能打包js。
2.plugin:用来扩展webpack其他方面的功能,一般loader处理不了的资源,完成不了的操作交给插件处理。

5.区别live-reload(自动刷新)与hot-realod/HMR(热模替换)

相同点:
  代码修改后都会自动重新编译打包
不同点:
  live-reload:刷新整体页面,从而查看到最新代码的效果,页面状态全部都是新的。
Hot-reload:没有刷新整个页面,只是加载了修改模块的打包文件并运行,从而更新页面的局部界面,整个界面的其他部分的状态还在

6.webpack常用loader与plugin汇总

loader:
  1.【less-loader】:用于将less文件翻译成为css
  2.【css-loader】:用于将css以commonjs语法打包到js中
  3.【style-loader】:用于动态创建一个style标签,将css引入页面
      备注:上述三个loader一般配合使用,最终实现:翻译less为css,以style标签形式将样式引入页面
  4.【file-loader】:提取源代码图片资源,到指定位置,可修改文件名等操作
  5.【url-loader】:与file-loader功能几乎一致,优势是可以对图片进行动态转换base64编码(控制limit属性值可以控制阈值)
      备注:上述两个loader中url-loader应用比file-loader广泛
  6.【jshint-loader】:对项目中的js语法进行检查,可选的配置项有:
      emitErrors: true/false
          -- emitErrors为true,检查出的错误显示为error(错误)类信息
          -- emitErrors为false,检查出的错误显示为warning(错误)类信息
      failOnHint: true/false
          -- failOnHint为true,当jshint检查出错误时,直接打断当前的代码的编译
          -- failOnHint为false,当jshit检查出错误时,会继续编译
      esversion:6
          -- 告诉jshint,不再提示新语法兼容性问题(有专门的loader解决新语法问题)
          -- 自定义一个报告错误的函数,输出想要的内容
       reporter: function(errors) {}
          -- 自定义一个报告错误的函数,输出想要的内容
  7.【babel-loader】:将es6语法转换为es5语法
          备注:该loader的使用要借助:babel-loader babel-core babel-preset-es2015
  8.【postcss-loader】:用于扩展css前缀
          备注:
              (1).该loader需要一个postcss.config.js配置文件
              (2).该loader要配合autoprefixer库使用
              (3).该loader使用的时机为:["css-loader","postcss-loader","less-loader"]

pulgin:
  1.【extract-text-webpack-plugin】:用于提取项目中的css,最终合并为一个单独的文件。
        备注:上述插件需要配合:css-loader、less-loader两个loader使用,css-loader、less-loader处理之后,交给extract-text-webpack-plugin处理
  2.【html-webpack-plugin】:自动创建html文件,且自动引入外部资源。配置项如下:
    title:"webpack",
    filename:"index.html",
    template:"./src/index.html"
    //用于压缩html
    minify:{
        removeComments: true, //移除注释
        collapseWhitespace: true //移除换行
    }
  3.【clean-webpack-plugin】:清空webpack的输出目录,防止其他文件“乱入”
  4.【HotModuleReplacementPlugin】:热模替换(HMR)插件
        备注:1.该模块必须配合webpack-dev-server模块使用,且webpack-dev-server中必须启用HMR
                    2.想要让指定文件支持HMR,必须要:
                        (1).无论是否有插件操作过该类型的资源,最终必须交给loader处理
                        (2).必须在入口文件中声明使用。
  5.【UglifyJsPlugin】:压缩js的插件,且可以生成sourceMap映射文件,用于方便排查错误
  6.【less-plugin-clean-css】:压缩css文件,在less-loader翻译less文件之后,该插件介入,开始压缩

你可能感兴趣的:(webpack3.0笔记)