Webpack入门到通晓(1)

媒介

什么是webpack 本质上,webpack 是一个当代 JavaScript 运用程序的静态模块打包器(module bundler)。当 webpack 处置惩罚运用程序时,它会递归地构建一个依靠关联图(dependency graph),个中包括运用程序须要的每一个模块,然后将一切这些模块打包成一个或多个 bundle。
webpack 有哪些功用(代码转换 文件优化 代码支解 模块兼并 自动革新 代码校验 自动宣布)
起首进修webpack 须要有简朴的node 基本 ,翻开node 官方网站举行装置node, http://nodejs.cn/ 下载最新版node包并举行装置。

进修目标:

  1. webpack 罕见设置 webpack高等设置
  2. webpack优化战略
  3. AST笼统语法树
  4. webpack中的Tapable
  5. 控制webpack流程 手写 webpack
  6. 手写webpack中罕见的loader
  7. 手写webpack 中罕见的plugin
  • 定义好进修目标让我们开启webpack 的新路程。(本文进修重要针对webpack4.0 举行进修解说)

webpck—>基本搭建与运用:

装置终了在终端 疾速建立node项目 实行敕令npm init -y 天生packge.json
在当前目次装置当地webpack
终端实行敕令:
npm i webpack webpack-cli -d
i示意install ,d示意当前是开辟环境装置完成会发生node_modules文件
webpack 能够举行0设置 而且webpack是打包东西(默许是js模块 经由过程进口举行打包输出打包后js效果)。
建立src目次 –> 建立index.js -> 输出:console.log(‘hello webpack’);
npx 语法举行把index.js 举行打包
终端实行敕令:
npx webpack
我们发明当前目次天生了一个dist 目次而且建立了一个main.js(如图:)
《Webpack入门到通晓(1)》
实行递次:(默许找node_modules—>bin文件 –> webpack文件 )
《Webpack入门到通晓(1)》
这里我们邃晓了装置webpack 必需装置他的依靠 webpack-cli
webpack打包默许支撑js模块化 ->类似于common.js

webpack:两种默两种情势假如没有建立webpack.config.js 设置文件指定mode (production/development)天生情势或开辟情势,打包运转会直接默许临盆情势打包而且举行紧缩。
这里说一下webpack设置文件的默许称号有两种 (webpack.config.js / webpackfile.js 平常情况下我们会挑选前一种)

怎样手动设置webpack呢?实在比较简朴

(1)建立webpack.config.js 设置文件 由于webpack是node.js的框架所以设置文件中要采纳node语法来举行编辑。

const path = require("path"); //webpack内部要领path组件
module.exports = {
  mode: "development", //打包情势 development开辟情势
  entry: "./src/index.js", //进口文件指定
  output: {
    //出口文件设置 设置出口打包途径
    filename: "build.js", //打包后的文件称号
    path: path.resolve(__dirname, "build") //resolve绝对途径引入
  }
};

我们剖析一下build.js 打包出的效果,默许下是一个匿名函数 而且吸收两个参数 吸收一个对象,Key : value (key:是当前模块的途径 value:是一个实行函数)
《Webpack入门到通晓(1)》
吸收到modules 里 先定义一个缓存对象 installedModules先定一个缓存目标是假如我当前模块加载完成没有必要再举行加载
webpack_require 完成了一个require要领由于浏览器没法直接实行node的require要领 (详解如图)
《Webpack入门到通晓(1)》
实行__webpack_require__ 发明吸收了一个进口模块
《Webpack入门到通晓(1)》

《Webpack入门到通晓(1)》
《Webpack入门到通晓(1)》
终端运转: npx webpack , 发明我们打包当前目次发生了文件夹build目次
剖析了一下打包文件是不是是觉得webpack 源码没有设想的那末难 继承我们webpack 的探索之旅。
怎样变动webpack 设置文件称号呢实在很简朴重命名webpack.config.js (webpack.test.js)
实行敕令:
npx webpack –config webpack.test.js 发明能够实行webpack打包。
如许打包我发明敕令很长所以我们运用packge.json 来设置打包剧本在scripts–>增加build.

"scripts": {
 "test": "echo \"Error: no test specified\" && exit 1",
 "build": "webpack --config webpack.config.js"
  }

终端运转 npm run build 发明实行打包效果一样.
(2)webpack 其他配 –>置插件的运用不会天生文件会天生内存中的打包
装置webpck内置效劳 webpack-dev-server 优点是
终端实行敕令: npm i webpack-dev-server -d -save
装置完成能够实行 npx webpack-dev-server 按提醒翻开http://localhost:8080/
怎样设置开辟效劳运转目次能够在设置文件中增加在webpack.config.js增加devServer

const path = require("path");
module.exports = {
  mode: "development", //打包情势
  entry: "./src/index.js", //进口文件指定
  output: {
    //出口文件设置 设置出口打包途径
    filename: "build.js", //打包的文件称号
    path: path.resolve(__dirname, "build") //resolve绝对途径引入
  },
  devServer: {
    //开辟效劳器设置
    contentBase: "./build", //指向打包目次
    port: 3000, //效劳端口号
    progress: true, //打包进度
    open: true, //是不是翻开浏览器
    compress: false //是不是紧缩
  }
};

在packge.json中增加start 启动效劳剧本

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --config webpack.config.js",
    "start":"webpack-dev-server"
  }

运转 npm run start 发明没有自动建立index.html 不能直观看到我们代码在浏览器的实行。
在src目次下建立html模板 index.html 并装置 html-webpack-plugin 插件
终端运转: npm i -d html-webpack-plugin
在webpack.config.js 下增加插件设置plugins

const path = require("path");
const HtmlWebPackPlugin = require("html-webpack-plugin");
module.exports = {
  mode: "development", //打包情势
  entry: "./src/index.js", //进口文件指定
  output: {
    //出口文件设置 设置出口打包途径
    filename: "build[hash:8].js", //打包的文件称号 filename: "build[hash:8] 增加哈希值
    path: path.resolve(__dirname, "build") //resolve绝对途径引入
  },
  devServer: {
    //开辟效劳器设置
    contentBase: "./build", //指向打包目次
    port: 3000, //效劳端口号
    progress: true, //打包进度
    open: true, //是不是翻开浏览器
    compress: false //是不是紧缩
  },
  //插件
  plugins: [
    //数组情势 寄存一切的webpack插件
    new HtmlWebPackPlugin({
      filename: "index.html", //天生打包文件名
      template: "./src/index.html", //模板途径
      minify: { //临盆情势能够举行设置
        removeAttributeQuotes: true, //删除 html文件双引号
        collapseWhitespace: true //摺叠控行
      },
      hash:true, //增加哈希值
    })
  ]
};

终端实行打包测试:npm run build (build目次下天生了我们想要天生的index.html文件)

款式的设置 webpack设置css模块:

设置款式须要一个适宜loader,loader会将我们的款式文件剖析成模块(module)
终端:npm i -d –save css-loader style-loader
怎样运用款式loader举行设置呢? 我们先在src下建index.css并给body给予简朴款式
在webpack.config.js 举行简朴设置
css-loader重要剖析我们款式中@import语法,style-loader是吧css款式插进去head标签中.

+ module: {
    //增加模块模块是对象
    rules: [
      //划定规矩 css-loader重要剖析我们款式中@import语法
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"] //实行递次是重右向左实行 - >重下到上
      }
    ]
  }

在index.js中引入款式文件 import ‘./index.css’
终端运转:npm run start 款式见效了一样我们也有对应的less less-loader
终端:npm i -d –save less less-loader
在这里说一下loader 的另一种写法对象写法能够给loader增加一些属性options

+ module: {
    //增加模块模块是对象
    rules: [
      //划定规矩 css-loader重要剖析我们款式中@import语法
      {
        test: /\.css$/,
        use: [ 
           {
            loader: "style-loader",
            options: {
              insertAt: "top" //把标签插进去顶部
            }
          }, 
          "css-loader"
          ] //实行递次是重右向左实行 - >重下到上
      },
      {
        test: /\.less$/,
        use: [
            {
            loader: "style-loader",
            options: {
              insertAt: "top" //把标签插进去顶部
            }
          }, 
          "css-loader",
          "less-loader"
        ] //实行递次是重右向左实行 - >重下到上
      }
    ]
  }

css 款式的抽离 装置抽离插件 mini-css-extract-plugin npm i -d –save mini-css-extract-plugin
引入插件并在设置文件中举行设置

const path = require("path");
const HtmlWebPackPlugin = require("html-webpack-plugin");
const MinCssExtractPlugin = require("mini-css-extract-plugin"); //抽离css插件
module.exports = {
 mode: "development", //打包情势
 entry: "./src/index.js", //进口文件指定
 output: {
   //出口文件设置 设置出口打包途径
   filename: "[name][hash:8].js", //打包的文件称号 filename: "build[hash:8] 增加哈希值
   path: path.resolve(__dirname, "build") //resolve绝对途径引入
 },
 devServer: {
   //开辟效劳器设置
   contentBase: "./build", //指向打包目次
   port: 3000, //效劳端口号
   progress: true, //打包进度
   open: true, //是不是翻开浏览器
   compress: false //是不是紧缩
 },
 //插件
 plugins: [
   //数组情势 寄存一切的webpack插件
   new HtmlWebPackPlugin({
     filename: "index.html", //天生打包文件名
     template: "./src/index.html", //模板途径
     minify: {
       removeAttributeQuotes: true, //删除 html文件双引号
       collapseWhitespace: true //摺叠控行
     },
     hash: true //增加哈希值
   }),
   new MinCssExtractPlugin({
     filename: "mian.css"
   })
 ],
 module: {
   //增加模块模块是对象
   rules: [
     //划定规矩 css-loader重要剖析我们款式中@import语法
     {
       test: /\.css$/,
       use: [
         MinCssExtractPlugin.loader, //建立link标签放入到main.css里
         "css-loader"
       ] //实行递次是重右向左实行 - >重下到上
     },
     {
       test: /\.less$/,
       use: [
         MinCssExtractPlugin.loader, //建立link标签放入到main.css里
         "css-loader",
         "less-loader"
       ] //实行递次是重右向左实行 - >重下到上
     }
   ]
 }
}

增加款式前缀 postcss-loader autoprefixer
npm i postcss-loader autoprefixer -d

 module: {
    //增加模块模块是对象
    rules: [
      //划定规矩 css-loader重要剖析我们款式中@import语法
      {
        test: /\.css$/,
        use: [
          MinCssExtractPlugin.loader, //建立link标签放入到main.css里
          "css-loader",
          "postcss-loader"
        ] //实行递次是重右向左实行 - >重下到上
      },
      {
        test: /\.less$/,
        use: [
          MinCssExtractPlugin.loader, //建立link标签放入到main.css里
          "css-loader",
           "postcss-loader",
          "less-loader" 
        ] //实行递次是重右向左实行 - >重下到上
      }
    ]
 }
  • 注重 postcss-loader 须要增加一个设置文件不然不会见效更目次建立postcss.config.js
module.exports = {
  plugins: [require("autoprefixer")]
};

然则我们发明问题运用mini-css-extract-plugin插件致使我们css不会被紧缩。
npm 官网有给出To minify the output, use a plugin like optimize-css-assets-webpack-plugin. Setting optimization.minimizer overrides the defaults provided by webpack, so make sure to also specify a JS minimizer:参考链接

要运用optimize-css-assets-webpack-plugin 插件接下来我们装置设置一下.
npm i -d optimize-css-assets-webpack-plugin

const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin"); //紧缩js
//设置文件中增加优化项
optimization: {
    minimizer: [new OptimizeCSSAssetsPlugin({})]
  }

运用optimize-css-assets-webpack-plugin我们发明js右不会被紧缩 所以要运用uglifyjs-webpack-plugin –save-dev
$ npm install uglifyjs-webpack-plugin –save-dev
设置产考链接

const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin"); //紧缩js
//设置文件中增加优化项
optimization: {
    minimizer: [new OptimizeCSSAssetsPlugin({}),new UglifyJsPlugin()]
  }

语法的转换 babel

在index.js 里写点es6语法箭头函数

let fn = () => {
  console.log("es6 webpack");
};
fn();

终端实行: npx webpack 检察打包文件
《Webpack入门到通晓(1)》
–我们发明打包出来的仍然是es6语法这个时刻我们须要一个loader 举行转换 babel-loader babel @babel/core
(babel/core是@babel-loader的中心组件转化模块@babel/preset-env) 参考链接
终端运转:npm i -d babel-loader babel @babel/core @babel/preset-env
在module增加设置

 //在rules下增加设置
 {
        test: /\.js$/,
        use: [
          {
            loader: "babel-loader",
            options: {
              //转化es5语法--presets预设
              presets: ["@babel/preset-env"]
            }
          }
        ]
      },

终端运转:npm run build
《Webpack入门到通晓(1)》
发明能够已转换es6语法 然则仅仅如许不能转换es6高阶语法比方一些特别的类函数

class Test {
  // new Test() a =1 实例上增加a属性 这个语法属于es7语法打包时发明并不能剖析
  a = 1;
}

终端运转:npm run build 发明报错提醒装置 @babel/plugin-proposal-class-properties
《Webpack入门到通晓(1)》
那我们依据请求依据一下插件 npm i -d @babel/plugin-proposal-class-properties 并举行一次设置

 //在rules下增加设置
 {
        test: /\.js$/,
        use: [
          {
            loader: "babel-loader",
            options: {
              //转化es5语法--presets预设
              presets: ["@babel/preset-env"],
               plugins: ["@babel/plugin-proposal-class-properties"]
            }
          }
        ]
      },

另有一种写法 装潢器@Log打包也是不被剖析的 在js 增加
《Webpack入门到通晓(1)》
依据毛病提醒装置decorators-legacy 参考链接 装置官方给出设置增加

 //在rules下增加设置
 {
        test: /\.js$/,
        use: {
          {
            loader: "babel-loader",
            options: {
              //转化es5语法--presets预设
              presets: ["@babel/preset-env"],
               plugins: [ //这里要注重增加递次
                 ["@babel/plugin-proposal-decorators", { legacy: true }],
                ["@babel/plugin-proposal-class-properties", { loose: true }]]
            }
          }
    
      },

转化完语法接下来看一下babel语法的校验 @babel/plugin-transform-runtime @babel/runtime参考链接

  {
        test: /\.js$/,
        use: {
          loader: "babel-loader",
          options: {
            //转化es5语法--presets预设
            presets: ["@babel/preset-env"],
            plugins: [
              ["@babel/plugin-proposal-decorators", { legacy: true }],
              ["@babel/plugin-proposal-class-properties", { loose: true }],
              [
                "@babel/plugin-transform-runtime",
                {
                  absoluteRuntime: false,
                  corejs: false,
                  helpers: true,
                  regenerator: true,
                  useESModules: false
                }
              ]
            ]
          }
        },
        include: path.resolve(__dirname, "src"), //只找__dirname - >src
        exclude: /node_modules/ //疏忽node_modulse
      },

includes 实例要领不被剖析 须要一个补丁模块@babel/polyfill
npm install –save @babel/polyfill
Babel includes a polyfill that includes a custom regenerator runtime and core-js.
运用能够直接在js 里引入即可。
接下来看一下代码校验ESLint代码校验东西参考链接
终端装置 npm i -d eslint eslint-loader
依据项目需求下载对应的eslintrc.json 下载链接

 //代码校验eslint
      {
        test: /\.js$/,
        use: {
          loader: "eslint-loader",
          options: {
            enforce: "pre" //强制实行递次
          }
        }
      },

DEMO

  • 本文回忆 1、webpack基本功用 build.js 打包的道理及源码剖析 2、webpack基本设置及经常使用插件设置装置 3、loader的运用与设置款式的处置惩罚 4、webpack优化项的简朴运用 5、babel语法转换与运用 babel语法校验 . 完成以上我置信人人能够控制并搭建简朴webpack项目。
  • 第二章我们将解说webpack 其他组件的设置及webpack优化项 webpack图片处置惩罚 多进口运用)
    原文作者:LeapFE
    原文地址: https://segmentfault.com/a/1190000019244310
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞