zoukankan      html  css  js  c++  java
  • webpack笔记

    前端必备打包工具!

    中文文档地址:https://webpack.docschina.org

    介绍

    Webpack 是一个开源的前端打包工具。Webpack 提供了前端开发缺乏的模块化开发方式,将各种静态资源视为模块,并从它生成优化过的代码。

    要使用 Webpack 前须先安装 Node.js。Webpack 其中一个特性是使用加载器来将资源转化成模块。开发者可以自定义加载器的顺序、格式来因应项目的需求。

    安装

    webpack 不推荐全局安装,安装命令为:

    npm install --save-dev webpack
    # 安装指定版本
    npm install --save-dev webpack@<version>
    
    # 如果你使用 webpack 4+ 版本,你还需要安装 CLI。
    npm install --save-dev webpack-cli
    

    快速创建一个 webpack 工程可以这样:

    mkdir webpack-demo && cd webpack-demo
    npm init -y
    npm install webpack webpack-cli --save-dev
    

    基本使用

    最简单的打包命令:webpack abc.js abc.bundle.js

    或者可以使用配置文件来进行打包,配置文件默认名为:webpack.config.js ,或者可以使用 --config 来指定那个文件。

    module.exports = {
      // 打包的入口文件
      entry: './src/index.js',
      output: {
        filename: 'bundle.js',
        path: './dist/js'
      }
    };
    

    有了这个配置文件,就可以直接在命令行中执行 webpack 了。

    除了这两种,还可以使用 npm 的脚本来运行,在 package.json 文件中新加一个自定义脚本:

    {
      "name": "webpack-demo",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "test": "echo "Error: no test specified" && exit 1",
    		"build": "webpack --progress --colors"
      },
      "keywords": [],
      "author": "",
      "license": "ISC",
      "devDependencies": {
        "webpack": "^4.0.1",
        "webpack-cli": "^2.0.9",
        "lodash": "^4.17.5"
      }
    }
    

    然后执行 npm run build 执行就可以得到相同的效果。

    这样在 HTML 中只需要引用这个打包后的文件就 ok 了,其他不需要考虑。

    关于模块化,webpack 支持 CommonJs, AMD, ES6 语法格式;其中最常用的就是 importrequire和 export语句了。

    PS:require 属于 CommonJs;

    默认 webpack 只支持 js 进行打包,想要打包 css 文件需要安装相应的 load:

    npm install css-loader style-loader --save-dev

    然后引用的时候这样写:require('style-loader!css-loader!./style.css') ,这里使用的是 CommonJs 的写法,因为暂时写在 js 文件里做测试,所以就先这样了;其中使用了两个 loader ,style-loader 是让 css 生效,css-loader 是让 webpack 可以正确的打包。

    通过 style-loader 会直接将其打包的 css 插入到 head 标签里。

    另一种写法就是在命令行中指定 loader :

    webpack xx xx.bundle.js --module-bind 'css=style-loader!css-loader'

    参数

    使用 webpack 命令可以在后面追加一些参数,比如:

    • --watch :实时监视部署生效
    • --progress :显示进度
    • --display-modules :查看所有的引用的(打包的)模块
    • --display-reasons :显示打包的原因(为什么要打包)

    打包配置

    前面简单提到过使用 webpack.config.js 进行打包,但是如果其中的 entry 有多个呢?可以使用数组进行添加~

    如果每个之间是独立的呢?可以使用对象的形式来书写:

    module.exports = {
      // 打包的入口文件
      entry: {
        app: './src/app.js',
        search: './src/search.js'
      },
      output: {
        filename: '[name].js',
        path: '/dist',
        // 多用于线上部署,引用地址会被替换为 publicPath 开头的地址
        // 差不多是 publicPath + path 的拼接形式
        publicPath: 'http://abc.com'
      }
    };
    

    entry (或者叫 chunks)使用对象的形式打包多个的时候,如果 output 中 filename不做相应的处理写死的话,那么后面的其实会覆盖前面的,最终只会生成一个文件。

    所以就需要使用所谓的“占位符”了,常见的占位符有:

    • [name]
      使用模块名称

    • [id]
      使用内部 chunk id ,或者叫模块标识符(module identifier)

    • [chunkhash]
      chunk 内容的 hash

    管理输出

    到目前为止,我们在 index.html 文件中手动引入所有资源,然而随着应用程序增长,并且一旦开始对文件名使用哈希 (hash)] 并输出多个 bundle,手动地对 index.html 文件进行管理,一切就会变得困难起来。然而,可以通过一些插件,会使这个过程更容易操控。

    这里,我们用 HtmlWebpackPlugin 来解决这个问题。 安装命令:

    npm install --save-dev html-webpack-plugin

    然后在 webpack.config.js 文件中更新配置:

    const HtmlWebpackPlugin = require('html-webpack-plugin');
    module.exports = {
      entry: {
        app: './src/index.js',
        print: './src/print.js'
      },
      plugins: [
        new HtmlWebpackPlugin({
          title: 'Output Management'
        })
      ],
      output: {
        filename: 'js/[name].bundle.js',
        path: './dist'
      }
    };
    

    注意 plugins 中添加的内容,然后观察一下就可以看出,输出的 HTML 文件自动添加了 打包后 js 的引用,位置在配置的 output 中的 path 路径下.

    当配置了多个 entry 后,最终生成、引入多个 entry,前提是你 output 使用了占位符。如果不指定 inject 默认是放在 body 中进行引用。

    除此之外,可以指定其他的一些 HtmlWebpackPlugin 参数:

    {
      // ...
      plugins: [
        new HtmlWebpackPlugin({
          // 插入引用在什么地方,比如 head
          inject: false,
          // 根据某个文件为模板,在此基础上添加引用
          template: 'index.html',
          // 默认就是 index.html
          filename: 'index.html',
          title: 'webpack is good',
          // 启用压缩
          minify: {
            removeComments:true, //删除注视
            collapseWhitespace: true //删除空格
          }
          // And any other config options from html-webpack-plugin:
          // https://github.com/ampedandwired/html-webpack-plugin#configuration
        })
      ]
    }
    

    并且是可以进行传值的,这里可以通过 title 属性(或者自己随便写一个)来测试,在模板文件中使用 ejs 模板取值:

    <%= htmlWebpackPlugin.options.title %>

    模板中遍历其属性的例子:

    <% for (var key in htmlWebpackPlugin.files){ %>
      // 为了避免 key/val 是一个对象情况,直接转成 json 输出
      <%= key %> : <%= JSON.stringify(htmlWebpackPlugin.files[key]) %>
    <% } %>
    
    <% for (var key in htmlWebpackPlugin.options){ %>
      <%= key %> : <%= JSON.stringify(htmlWebpackPlugin.options[key]) %>
    <% } %>
    

    PS:htmlWebpackPlugin.files.chunks['app'].entry 就可以拿到 chunk app 定义的文件名称,然后就可以使用 <%= %> 的方式写入到 script 标签的 src 引用中;或者更简单的让其自动添加(inject)。

    多页面

    多页面就是输出生成多个页面,可以看到在配置文件中 plugins 对应的是一个数组,也就意味着可以传入多个插件,同时也可以传入多个相同的插件,比如 HtmlWebpackPlugin,可以根据相同的页面指定不同的模板,或者不同的页面相同的模板。

    {
      // ...
      entry: {
        app: './src/index.js',
        print: './src/print.js'
      },
      plugins: [
        new HtmlWebpackPlugin({
          // 插入引用在什么地方,比如 head
          inject: body,
          // 根据某个文件为模板,在此基础上添加引用
          template: 'index.html',
          // 默认就是 index.html
          filename: 'index.html',
          title: 'webpack is a',
          // 排除不需要引用的 entry
          excludeChunks: ['app']
        }),
        new HtmlWebpackPlugin({
          // 插入引用在什么地方,比如 head
          inject: body,
          // 根据某个文件为模板,在此基础上添加引用
          template: 'index.html',
          // 默认就是 index.html
          filename: 'index.html',
          title: 'webpack is b',
          // 执行需要引入的 entry
          chunks: [app]
        })
      ]
    }
    

    在 entry 中有多个文件的情况下,根据需求,配置好 excludeChunks 或者 chunks 就好了。

    处理资源文件

    css、图片压缩、ES6 语法转换等等

    使用Loader

    Loader 专门用来处理资源,前面其实已经简单的接触过了(通过 require 的方式和 CLI 就是命令行的方式),可以使用它来支持那些 webpack 默认不支持的,支持串联的方式。

    然后是第三种使用方式,上面没有学过的,使用配置文件来定义规则。

    webpack.config.js 中定义:

    module.exports = {
      module: {
        rules: [
          // 根据正则进行匹配,loader 使用串联
          { test: /.css$/, use: 'style-loader!css-loader' }, // js 中可以导入 css,并且自动插入到 HTML
          { test: /.ts$/, use: 'ts-loader' },
          // 处理 ES6 语法
          {
            test: /.js$/,
            loader: 'babel',
            // loaders: []
            // 也可以在 package.json 中指定
            query: {
              presets: ['latest']  // 指定 ES6 的版本,比如 es2015 等
            },
            // 还可以使用 exclude、include 进行优化速度
            exclude: './node_modules/'
          }
        ]
      }
    };
    

    引用的这些插件是需要安装的,npm 安装下就好。

    loader 的处理方式是从右到左的,并且是可以省略后面的 -loader 的。

    处理图片资源

    处理图片资源可以使用 file-loader,引用方式和上面一样:

    module.exports = {
      module: {
        rules: [
          // ...
          {
            test: /.(png|jpg))$/i,
            loader: 'file-loader',
            query: {
              // 将名字按照指定格式处理
              name: 'assets/[name]-[hash:5].[ext]'
            }
          }
        ]
      }
    };
    

    在模板中引用图片地址时,尽量使用绝对地址,使用相对地址不会处理的;实在是想用相对地址可以通过 require 实现:

    src="${ require('../abc.jpg') }"

    再说一个相似的 loader :url-loader,它和 file-loader 非常相似,它可以设定一个 limit 值(query 中,单位字节),当图片超过这个大小就丢给 file-loader 处理,如果小于这个值就直接转成 url 图片编码的格式。

    想要压缩图片可以使用 image-loader,官方建议配合 url-loader 或者 file-loader 使用。

    module.exports = {
      module: {
        rules: [
          // ...
          {
            test: /.(png|jpg))$/i,
            loaders: [
              'url-loader?limit=10000&name=assets/[name]-[hash:5].[ext]',
              'image-webpack'
            ]
          }
        ]
      }
    };
    

    可以看出参数的设置可以使用 url 的方式;加载规则还是从右到左,也就是会先进行压缩。

    对于每一种图片格式都有相应的优化器,在官网可以找到这些配置。

    其他

    使用 Node 的自带 API 生成绝对路径:

    var path = require('path');
    
    // 使用
    path.resolve(__dirname, 'src');
    

    其他常用的模块比如:postcss-loader 能自动生成浏览器前缀,配合 autoprefixer 插件使用。

    使用 Vue 的话可以使用 jsx 语法的 loader,babel 已经支持。

  • 相关阅读:
    [C#]StringWriter实现的一个功能
    ASP.NET AJAX入门系列(1):概述
    ASP.NET 2.0 之 Master Page 学习笔记
    C#文件读写常用类介绍
    最新版FreeTextBox(版本3.1.6)在ASP.Net 2.0中使用简解
    关于Ajax 错误:'sys'未定义解决方法.
    教你解决微软MSN8.5无法安装问题
    对于javascript的function的总结
    ASP.NET开发:在用户控件中添加属性
    如何遍历枚举类型的对象、并获取枚举类型长度
  • 原文地址:https://www.cnblogs.com/bfchengnuo/p/9193156.html
Copyright © 2011-2022 走看看