zoukankan      html  css  js  c++  java
  • Webpack 学习记录之概念

    1 什么是webpack

    webpack是一个模块打包器,可以递归的构建一个依赖关系图,其中包含每个程序需要的每个模块,然后将所有模块打包成一个或多个bundle。他和其他的工具最大的不同在于他支持code-splitting、模块化(AMD,ESM,CommonJs)、全局分析。

    bundle:bundle即由webpack打包出来的文件。

    依赖关系:一个文件依赖于另一个文件,webpack就把这种关系视为依赖关系。所以webpack可以接受非代码资源,并把它们当做依赖提供给应用程序。

    2 主要概念

    入口:entry指示webpack使用哪个文件作为构建依赖图的开始。

    出口: output指示webpack将打包好的bundles,如何命名以及输出到哪里。

    loader:loader可以让webpack如处理那些非JS文件,将起转化为模块(webpack只理解JS)

    插件:plugins可以打包优化和压缩等处理各种各样的任务。

    模式:mode设置为开发还是生产环境

      const path = require('path');
      const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装
      const webpack = require('webpack'); // 用于访问内置插件
      
      module.exports = {
        entry: './path/to/my/entry/file.js',
        output: {
          path: path.resolve(__dirname, 'dist'),
          filename: 'my-first-webpack.bundle.js'
       },
       module: {
         rules: [
           { test: /.txt$/, use: 'raw-loader' }
         ]
       },
       plugins: [
         new HtmlWebpackPlugin({template: './src/index.html'})
       ],
       mode:'production' || 'development'
     };

    3 详细示例

    3.1 入口 entry

    module.exports = {
        // 单个入口
        entry: './path/to/my/entry/file.js'
    
        // 为单个入口文件赋值名字
        entry: {
           main: './path/to/my/entry/file.js'
        }
        
        // 多文件多入口,一般用于分离 应用程序(app) 和 第三方库(vendor) 入口
        entry: {
            app: './src/app.js',
            vendors: './src/vendors.js'
         }
    }

    3.2 输出 output

    即使有多个入口文件,也只能规定一个输出配置

    module.exports = {
      // 最低要求,filename和path
      output:{
        filename:'bundle.js',
        path: '/home/proj/public/assets'
      }
    
      // 如果有多个入口文件,即生成多个单独的"chunk",则要使用占位符来确保每个文件具有唯一的名字
      output: {
        filename: '[name].js',
        path: __dirname + '/dist'
      }
    
    }

    3.3 模式 mode

    module.exports = {
      mode: 'production' //生产
      mode: 'development' //开发
    };

    3.4 loader

    由于webpack无法处理除了JS以外的文件,所以loader发挥了重要的作用。

    loader用于对模块的源代码进行转换,即将不同的语言转化为js,或将内联图转化为 data URL,也允许你直接在JS中import css文件,并且在bundle中引入这些依赖。

    // npm install --save-dev css-loader
    // npm install --save-dev ts-loader
    
    //在webpack.config.js中配置
    module.exports = {
      module: {
        rules: [
          { test: /.css$/, use: 'css-loader' },
          { test: /.ts$/, use: 'ts-loader' }
        ]
      }
    };
    
    // 使用内联方式配置
    import Styles from 'style-loader!css-loader?modules!./styles.css';
    
    // 通过 CLI 使用
    webpack --module-bind jade-loader --module-bind 'css=style-loader!css-loader'

    3.5 插件 plugins

     webpack 插件是一个具有 apply属性的 JavaScript 对象,用来解决loader无法实现的其他事。

    const HtmlWebpackPlugin = require('html-webpack-plugin'); //通过 npm 安装
    const webpack = require('webpack'); //访问内置的插件
    
    module.exports = {
      ....
      plugins: [
        new webpack.optimize.UglifyJsPlugin(),
        new HtmlWebpackPlugin({template: './src/index.html'})
      ]
    }

     

    4 概念补充

    4.1模块 module

    在模块化编程中,开发者将程序分解成离散功能块,并称之为模块。

    模块以各种方式表达他们的依赖关系:

    • es2015 import 语句
    • commonjs require() 语句
    • AMD define 和 require 语句
    • css/sass/less文件中的 @import 语句
    • 样式url(...)或HTML文件<img src=.../>中的图片链接

    4.2 模块解析 module resolution

    resolver是一个库,用于帮助找到模块的绝对路径。当打包模块时,webpack使用enhanced-resolve来解析文件路径。

    webpack中的解析规则:

    // 已经取得文件的绝对路径,不需要在做解析
    import "C:\Users\me\file";
    
    
    // 在import/require给定的相对路径,添加上下文路径,转化为绝对路径
    import "../src/file1";
    
    // 模块路径
    //(1)指定目录,如果目录具有扩展名,直接打包;如果没有,查看resolve.extensions 的值,看看接受那些扩展名,如.js,.jsx
    import "module";
    
    //(2)指向文件夹
    /*a.如果文件夹中包含 package.json 文件,则按照顺序查找 resolve.mainFields 配置选项中指定的字段。
    并且 package.json 中的第一个这样的字段确定文件路径。
    b.如果 package.json 文件不存在或者 package.json 文件中的 main 字段没有返回一个有效路径,则按照顺序查找 resolve.mainFiles 配置选项中指定的文件名,看是否能在 import/require 目录下匹配到一个存在的文件名。
    c.文件扩展名通过 resolve.extensions 选项采用类似的方法进行解析。*/
    import "module/lib/file";

    4.3 Runtime 与 Manifest

    在使用webpack构建的应用程序或站点中,有三种主要的代码类型:

    (1)你或你的团队编写的代码;

    (2)你的源码会依赖的任何第三方的 library 或 vendor 代码;

    (3)webpack 的 runtime 和 mainfest,管理所有模块的交互。

    当打包之后,应用程序的目录结构不复存在,webpack通过runtime与manifest管理各个模块之间的联系与交互。

    manifest保留着所有模块的详细要点(比如依赖于哪个模块),将import或require语句都转化为__webpack_require__方法,指向模块标识符。

    runtime根据manifest,查询模块标识符,实现模块的加载和逻辑解析。

    4.4 模块热替换 hot module replacement

    模块热替换会在应用程序运行过程中替换、添加或删除模块,而无需重新加载整个页面,主要通过以下方式来加快开发速度:

    (1)保留在完全重新加载页面时丢失的应用程序状态;

    (2)只更新变更的内容;

    (3)像在浏览器调试器中更改样式一样快。


    待理解之后补充:

    (1)模块路径指向文件夹的查找方式;

    (2)为何在使用缓存时,有些表面上的内容没有修改,计算出的哈希还是会改变。(文中原因::runtime和manifest的注入在每次构建都会发生变化);

    (3)模块热替换的原理。

  • 相关阅读:
    xss攻击和csrf攻击的定义及区别
    php中Redis的扩展
    MySQL事务特性
    PHP的设计模式
    http协议
    sql语句的优化
    mysql存储引擎
    laravel框架安装Curl扩展
    laravel框架中安装 elasticsearch 包
    docker容器配置nginx负载均衡 -----加权
  • 原文地址:https://www.cnblogs.com/armouy/p/9978608.html
Copyright © 2011-2022 走看看