webpack

作者: LiLi原上草 | 来源:发表于2017-07-12 18:06 被阅读14次

    一张图,看懂webpack

    webpack 是一个现代的 JavaScript 应用程序的模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图表(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成少量的 bundle - 通常只有一个,由浏览器加载。

    它是高度可配置的,但是,在开始前你需要先理解四个核心概念:入口(entry)、输出(output)、loader、插件(plugins)。

    概览

    app.js

    import bar from './bar'
    bar()
    

    bar.js

    export default function () {
        // ...
    }
    

    webpack.config.js

    module.exports = {
        entry: './app.js',
        output: {
            filename: 'bundle.js'
        }
    }
    

    index.html

    <html>
        <head>
            ...
        </head>
        <body>
            ...
            <script src="bundle.js"></script>
        </body>
    </html>
    

    起步

    参考地址: https://doc.webpack-china.org/guides/get-started/

    webpack is a tool to build JavaScript modules in your application.

    webpack 是一个用来构建我们应用程序中的 JavaScript 模块的工具

    创建一个bundle文件

    1. 在项目中创建package.json文件

      $ npm init -y
      
    2. 安装webpack到项目中

      $ npm install --save webpack
      
    3. app目录下创建index.js文件
      app/index.js

      function component () {
          var element = document.createElement('div');
      
          // 需要引入 lodash,下一行才能正常工作
          element.innerHTML = _.join(['Hello','webpack'], ' ');
      
          return element;
      }
      
      document.body.appendChild(component());
      

      要运行这段代码,在项目根目录下创建 index.html 文件。

      index.html

      <html>
          <head>
              <title>webpack 2 demo</title>
              <script src="https://unpkg.com/lodash@4.16.6"></script>
          </head>
          <body>
      
          </body>
          <script src="app/index.js"></script>
      </html>
      

      在此示例中,<script> 标签之间存在隐式依赖关系。

      运行 index.js 会依赖于页面中提前引入的 lodash。之所以说是隐式的是因为 index.js 并未显式声明需要引入 lodash,只是假定推测已经存在一个全局变量 _

      使用这种方式去管理 JavaScript 项目会有一些问题:

      • 如果依赖不存在,或者引入顺序错误,应用程序将无法正常运行。
      • 如果依赖被引入但是并没有使用,那样就会存在许多浏览器不得不下载的无用代码。
    4. 要在 index.js 中打包 lodash 依赖,首先我们需要安装 lodash

      $ npm install --save lodash
      

      app/index.js最上面添加此行代码,在文件内显示引入

      import _ from 'lodash'
      

      修改index.html文件,删除两行script标签的引入,改为引入dist/bundle.js

      <html>
          <head>
              <title>webpack 2 demo</title>
          </head>
          <body>
      
          </body>
          <script src="dist/bundle.js"></script>
      </html>
      
    5. 使用webpack,对app/index.js进行处理

      $ webpack app/index.js dist/bundle.js
      

      之后会生成一个dist文件夹,内部存在bundle.js文件
      刷新网页,效果是一样的!

      通过声明模块所需的依赖,webpack 能够利用这些信息去构建依赖图表,然后使用图表生成一个优化过的,会以正确代码顺序被运行的 bundle。并且没有用到的依赖将不会被 bundle 引入。

      现在在此文件夹下带上以下参数运行 webpack,其中 index.js 是入口文件,bundle.js 是已打包所需的所有代码的输出文件。

      说明: 尽管 import/export 语句在浏览器中还未被支持,你也可以正常的使用,因为 webpack 会将其替换为 ES5 兼容的代码。你可以检查 dist/bundle.js 的代码来说服自己放心使用

    使用配置好的文件

    对于更复杂的配置,我们可以使用一个配置文件,webpack 会按照它来打包代码。创建一个 webpack.config.js 文件后,你可以使用如下的配置设置来表示上述 CLI 命令。

    webpack.config.js

    var path = require('path');
    
    module.exports = {
        entry: './app/index.js',
        output: {
            filename: 'bundle.js',
            path: path.resolve(__dirname, 'dist')
        }
    };
    

    执行命令,进行压缩打包

    $ webpack --config webpack.config.js
    

    同样可以生成bundle.js文件

    通过配置文件可以最灵活地使用 webpack。我们可以通过向配置文件添加 loader 规则(loader rules)、插件(plugins)、解析选项(resolve options)以及许多其他增强功能,来进行打包。

    配合npm使用

    考虑到用 CLI 这种方式来运行 webpack 不是特别方便,我们可以设置一个快捷方式。像这样调整 package.json

    package.json添加如下代码:

    "scripts": {
        "build": "webpack"
    },
    

    通过执行命令,即可使用webpack进行打包压缩等操作

    $ npm run build
    

    概念解释

    入口(entry)

    webpack 将创建所有应用程序的依赖关系图表(dependency graph)。图表的起点被称之为入口起点(entry point)入口起点告诉 webpack 从哪里开始,并遵循着依赖关系图表知道要打包什么。可以将您应用程序的入口起点认为是根上下文(contextual root)app 第一个启动文件

    module.exports = {
        entry: './path/to/my/entry/file.js'
    };
    

    entry属性告诉我们主文件在哪里

    出口(output)

    将所有的资源(assets)归拢在一起后,还需要告诉 webpack 在哪里打包应用程序。webpack 的 output 属性描述了如何处理归拢在一起的代码(bundled code)。

    const path = require('path');
    
    module.exports = {
        entry: './path/to/my/entry/file.js',
        output: {
          path: path.resolve(__dirname, 'dist'),
          filename: 'my-first-webpack.bundle.js'
        }
    };
    

    通过 output.filenameoutput.path 属性,来告诉 webpack bundle 的名称,以及我们想要生成(emit)到哪里

    loader

    webpack 的目标是,让 webpack 聚焦于项目中的所有资源(asset),而浏览器不需要关注考虑这些(这并不意味着资源(asset)都必须打包在一起)。webpack 把每个文件(.css, .html, .scss, .jpg, etc.) 都作为模块处理。然而 webpack 只理解 JavaScript

    webpack loader 会将这些文件转换为模块,而转换后的文件会被添加到依赖图表中。

    在更高层面,webpack 的配置有两个目标。

    1. 识别出(identify)应该被对应的 loader 进行转换(transform)的那些文件
    2. 由于进行过文件转换,所以能够将被转换的文件添加到依赖图表(并且最终添加到 bundle 中)(use 属性)
    const path = require('path');
    const config = {
        entry: './path/to/my/entry/file.js',
        output: {
            path: path.resolve(__dirname, 'dist'),
            filename: 'my-first-webpack.bundle.js'
        },
        module: {
            rules: [
                {test: /\.(js|jsx)$/, use: 'babel-loader'}
            ]
        }
    };
    module.exports = config;
    

    以上配置中,对一个单独的 module 对象定义了 rules 属性,里面包含两个必须属性:testuse。这可以告诉 webpack compiler 如下:

    “嘿,webpack compiler,当你碰到「在 require()/import 语句中被解析为 '.js' 或 '.jsx' 的路径」时,在你把它们添加并打包之前,要先使用 babel-loader 去转换”。

    插件

    由于 loader 仅在每个文件的基础上执行转换,而 插件(plugins) 最常用于(但不限于)在打包模块的“compilation”和“chunk”生命周期执行操作和自定义功能(查看更多)。webpack 的插件系统极其强大和可定制化

    想要使用一个插件,你只需要 require() 它,然后把它添加到 plugins 数组中。多数插件可以通过选项(option)自定义。你也可以在一个配置文件中因为不同目的而多次使用同一个插件,你需要使用 new 创建实例来调用它。

    // 引入插件
    const HtmlWebpackPlugin = require('html-webpack-plugin'); //installed via npm
    const webpack = require('webpack'); //to access built-in plugins
    const path = require('path');
    
    const config = {
        entry: './path/to/my/entry/file.js',
        output: {
            path: path.resolve(__dirname, 'dist'),
            filename: 'my-first-webpack.bundle.js'
        },
        module: {
            rules: [
                {test: /\.(js|jsx)$/, use: 'babel-loader'}
            ]
        },
        plugins: [ // 创建插件对象,添加到此数组中
            new webpack.optimize.UglifyJsPlugin(),
            new HtmlWebpackPlugin({template: './src/index.html'})
        ]
    };
    
    module.exports = config;
    

    相关文章

      网友评论

        本文标题: webpack

        本文链接:https://www.haomeiwen.com/subject/peabhxtx.html