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

    声明:摘自  keliyxyz的博客

    (一)webpack介绍

    如今的网站正在演化为web应用程序: 
    1. 越来越多的使用JavaScript。 
    2. 现代浏览器提供更广泛的接口。 
    3. 整页刷新的情况越来越少,甚至更多代码在同一个页面。(SPA)

    因此有很多代码在客户端! 
    一个体量庞大的代码库需要好好组织。模块系统提供代码库划分成模块的选项。

    目前有多个标准定义依赖和输出: 
    1. script标签(不要模块系统) 
    2. CommonJS 
    3. AMD和它的一些变种 
    4. ES 6 
    5. 其它

    script 标签的样式

    下面这种就是不用模块系统,你会怎么去管理你的代码。

    <script src="module1.js"></script>
    <script src="module2.js"></script>
    <script src="libraryA.js"></script>
    <script src="module3.js"></script>

    模块接口导出到全局对象,即window对象。模块的接口可以访问全局对象的依赖关系 

    常见问题

    全局冲突 
    严重依赖加载的顺序 
    开发人员必须人工解决模块/库的依赖关系 
    大型项目,script一溜下来可以很长,难以管理

    CommonJs: 同步加载

    这种风格用同步require 的方法去加载一个依赖并用暴露一个接口。 一个模块可以通过给export对象添加属性或给module.exports设置值 来指定导出。

    require("module");
    require("../file.js");
    exports.doStuff = function() {};
    module.exports = someValue;

    服务器端node.js用的就是这种标准。 

    优点
    1. 服务器端模块可以重用 
    2. 已经有许多模块用这种风格(npm)。生态圈良好 
    3. 非常简单和容易使用。 

    劣势 
    1. 阻塞调用不适用网络。网络请求是异步的。 
    2. 没有并行加载机制。 

    哪些在用? 
    1. 服务端 -node.js 
    2. browserify 
    3. modules-webmake -编译到一个包 
    4. wreq -客户端

    AMD: 异步加载

    其它模块系统(例如 浏览器) 同步加载有困难(CommonJS) 而引入的一个异步版本(和定义模块和输出值的一种方法 )。

    require(["module", "../file"], function(module, file) { /* ... */ });
    define("mymodule", ["dep1", "dep2"], function(d1, d2) {
      return someExportedValue;
    });
    • 1
    • 2
    • 3
    • 4

    优点
    1. 适合网络的异步请求的风格 
    2. 并行加载多个模块。 
    劣势 
    1. 编码费力,更难读和写 
    2. 看起来只是权宜之计。 

    哪些在用? 
    1. require.js 
    2. curl

    ES6模式

    ES6借鉴其它语言给javascript新加了一些语法结构,有import语法。

    import "jquery";
    export function doStuff() {}
    module "localModule" {}
    • 1
    • 2
    • 3

    优点
    1. 静态分析很容易。 
    2. 不会过时的ES标准 。 
    劣势 
    1. 浏览器支持需要时间。(迟早的事) 
    2. 很少有模块用这种风格。生态圈 

    目前没有公开的方案

    开发者应当自己选择适合自己的风格。允许现有的代码和包能正常工作,可以很容易地添加自定义模块风格。

    传输

    模块应该在客户端执行,所以他们必须从服务器传输到浏览器。 
    传输模块有两个极端: 
    1. 一个一个地传。 
    2. 全部打包在一个里传。

    两种用法都泛滥,但是两种都太low了。

    一个一个地传 
    优点:只有确实需要的模块才会传输过去。 
    缺点:许多请求意味着很多开销。 
    缺点:应用程序启动缓慢,因为请求延迟 
    全部一个地传 
    优点:请求的开销更少,更少的延迟 
    缺点:很多暂时不需要的模块给传输过去了。

    分块传输

    更灵活的传输可能会更好。大多数情况下在这两种极端之间的折中比较好。 

    =>在编译所有模块时:把模块切分成小块儿(chunks)。 
    这样允许多个更小、更快的请求。有些模块不是一开始就需要的,含有这些模块的分块在需要的时候可以加载到。这样加快了初始化速度,但是在需要用那些模块时仍然让你去抓更多的代码。

    开发者怎么做“切分点”,可以根据情况自由抉择。 
    =》一个代码库是可能的哟。

    注意:这些观点来自谷歌 GWT.

    =>在编译所有模块时:把模块切分成小块儿(chunks)。 
    这样允许多个更小、更快的请求。有些模块不是一开始就需要的,含有这些模块的分块在需要的时候可以加载到。这样加快了初始化速度,但是在需要用那些模块时仍然让你去抓更多的代码。

    开发者怎么做“切分点”,可以根据情况自由抉择。 
    =》一个代码库是可能的哟。

    注意:这些观点来自谷歌 GWT.

    静态分析

    当编译所有这些模块时,一个静态分析试图找到自己的依赖。 
    传统上这只能找到简单的东西没有表达 。但是 
    require("./template/" + templateName + ".jade") 这样是常见的结构。 
    有些库是用一些不一样的风格写的。它们有些很奇怪(不可思议)。

    策略

    聪明的解析办法允许现存代码能跑起来,如果程序猿用了一些怪异的东西,它能试图找到兼容的解决方案。

    什么是webpack

    webpack是一个模块打包器。webpack把模块(s)连同它的依赖一起打包生成包含这些模块的静态资源。

    为什么另用一个打包器?

    现有的模块打包器不适合大项目(大单页面应用)程序。代码分割和静态资源无缝模块化的迫切需求,催生了一个新的模块打包器。 
    我试图扩展现有的模块打包器,但是它没能实现所有的目标。 

    目标如下: 
    1. 把依赖树切分成块,实现按需加载。 
    2. 保持低初始加载时间 
    3. 每个静态资源都能是一个模块 
    4. 具备把第三方库集成为模块的能力 
    5. 具备打包器每个部分几乎都能自己定制的特点。 
    6. 适合大型项目。

    webpack有什么不同?

    代码分割

    webpack依赖树中有两个依赖类型:同步和异步。异步模块切分成一个新的块。在块树(chunk tree)优化之后,文件会为每个chunk发文件。

    loader

    webpack可以处理javascript本身,但loader用来将其它资源转换为javascript。这样一来,所有资源都被格式化成模块了。

    智能解析

    webpack有一个智能解析器,它能处理几乎所有的第三方库。它甚至允许你在依赖中像这样加表达式 require("./templates/" + name + ".jade") 。它可以处理最常见的模块化标准风格:CommonJS和AMD。

    安装

    node.js

    安装node.js 
    包管理工具 npm会一起装上。

    webapck

    webpack 可以用npm 命令来装

    $ npm install webpack -g

    webpack 已经全局安装了,现在 webpack 命令可用了。

    项目中使用webpack

    你的项目最好也有webpack 依赖。 这样你可以在项目中自由决定用webpack哪个版本而不必去用全局那个webpack。 
    用 npm 命令添加一个 package.json文件

    $ npm init

    如果你不发布npm包,Init过程中的问题不重要,都可以忽略。 
    安装webpack 并添加到package.json中:

    $ npm install webpack --save-dev

    版本

    有两个webpack版本可用。稳定版本和beta版。beta版 在版本字符中标记为 -beta 。beta版本可能包含脆弱的或者实验功能,都没进行过多少测试。正式场景下应该用稳定版。

    $ npm install webpack@1.2.x --save-dev

    开发工具

    如果你想用开发工具,先安装它

    $ npm install webpack-dev-server --save-dev

    (二)webpack 使用

    安装

    可以用 npm 安装

    npm install webpack -g

    注意: 这里全局安装是出于演示的目的。在真实的项目中,建议安装为你的项目依赖。

    开始

    首先,我们将只使用webpack的命令行界面学习基本webpack 。

    新建一个 模块化的javascript 项目

    cats.js

    var cats = ['dave', 'henry', 'martha'];
    module.exports = cats;

    app.js (入口文件)

    cats = require('./cats.js');
    console.log(cats);

    入口文件就是你项目启动点。也是webpack追踪模块之间依赖关系的入口点。

    5秒 打包

    给webpack指定一个入口文件(app.js)和输出文件(app.bundle.js)

    webpack ./app.js app.bundle.js

    webpack将读取和分析入口点及其依赖(包括传递的依赖)。然后它会把它们都打包到app.bundle.js。 
    现在你打好的包可以跑起来了。 运行一下 node app.bundle.js ,你会发现,哇,你有好多猫。

    node app.bundle.js
    ["dave", "henry", "martha"]

    你也可以在 浏览器端使用打好的包。

    来点严肃的

    webpack是一个非常灵活的模块打包器。它提供了很多高级功能,但并非所有功能都通过命令行界面实现。要获得全部webpack的灵活性,我们需要创建一个 config 文件

    项目结构

    在真实的webpack项目中,我们会把源文件和打包文件用文件夹分开。在这个例子中,我们把源文件放在src中,把打包后的文件放在bin中。 
    结构如下

    project
    └─webpack.config.js
    └─src
      └─app.js
      └─app.js
    └─node_modules
    └─bin
      └─app.bundle.js

    大千世界,无奇不有。有不少不一样的结构。有些项目用app而不是src,用些用dist 或者 build而不是bin.项目测试学用 test,tests,spec,specs或者把测试文件放在源文件夹一起。

    1.创建 bin 和 src 文件夹。

     mkdir bin
     mkdir src

    2.原始源文件移动到src文件夹

    mv app.js cats.js src

    3.初始化一个新项目。

    npm init # (answer the questions)

    4.安装webpack为你的项目开发依赖。这将声明你的项目适用webpack版本。

    npm install --save-dev webpack

    迁移到config文件

    随着你项目越来越大,你的配置文件也会越来越复杂。从命令行配置webpack就显得很不科学。我们来创建一个配置文件。 
    1.创建 webpack.config.js

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

    webpack 配置文件是 node 风格的模式。所以您可以运行任何类型的代码,只要一个配置对象,导出了配置模块。

    2.在放了配置文件的地方,你可以简单地运行一下 webpack:

    webpack

    3.运行 bin/app.bundle.js ,你又可以拿到你的猫了

    node bin/app.bundle.js
     ["dave", "henry", "martha"]

    你也可以 require 用npm安装过的模块,而不需要额外的配置。

    使用loader

    webpack原生只支持javascript模式。但是许多人会用像es 2015 ,coffeeScript ,typeScript 等语言。这些语言是可以用的,要用“loader”处理它们。 
    loader是一种用来加载其它语言到javascript(webapck能够理解)的特殊的模块 。例如,babel-loader 用Babel 加载 ES2015文件。json-loader 加载JSON文件(简单地在前面加上 module.exports= 来把它转换成 CommonJS模式) 
    。loader可以链式调用,而且你通常需要这么做。例如,yaml-loader 只把 YAML转换为 JSON,因此你需要 把它链到 json-loader 这样就可以用啦。

    用 babel-loader 转换 ES2015

    在这个例子中, 我们会告诉 webpack 用 babel 跑我们的源码,这样就可以用 ES2015新特性了。 

    1.先安装 babel 和 预设。

    npm intall  --save-dev babel-core babel-preset-es2015

    2.安装 babel-loader

    npm install --save-dev babel-loader

    3.添加 .babelrc 文件来配置 babel 使用 规范。

    4.修改 webpack.config.js 用babel-loader 处理 .js文件。

    module.exports = {
         entry: './src/app.js',
         output: {
             path: './bin',
             filename: 'app.bundle.js',
         },
         module: {
             loaders: [{
                 test: /.js$/,
                 exclude: /node_modules/,
                 loader: 'babel-loader',
             }]
         }
     }

    我们排除 node_modules中的文件,因为要不然的话所有外部库都会通过babel编译,将会降低 编译速度。

    5.安装你想用的第三方库。(例如 jQuery)

    npm install --save jquery babel-polyfill

    这里用 –save 而不是 –save-dev, 是因为这些库在执行时会用到。我们也安装了babel-polyfill 这样在一些老式浏览中可以用 ES2015了。

    6.编辑 src/app.js

     import 'babel-polyfill';
     import cats from './cats';
     import $ from 'jquery';
    
     $('<h1>Cats</h1>').appendTo('body');
     const ul = $('<ul></ul>').appendTo('body');
     for (const cat of cats) {
         $('<li></li>').text(cat).appendTo(ul);
     }

    7.用webpack 打包

    webpack

    8.添加 index.html,这样app能跑起来。

    <!DOCTYPE html><body>
     <script src="bin/app.bundle.js"></script>

    当你打开 index.html 时你应该能看到你的猫了。

    有许多不同的loders你可以用在app打包中,包括 css 和 image loader。

    用插件

    通常你需要在你的打包工作流中做一些额外的事情。一个简单的例子是你会压缩文件来使客户端加载起来更快,这就可以用插件来做。我们将添加 uglify 插件到配置中。

    用插件

    通常你需要在你的打包工作流中做一些额外的事情。一个简单的例子是你会压缩文件来使客户端加载起来更快,这就可以用插件来做。我们将添加 uglify 插件到配置中。

    const webpack = require('webpack');
    
    module.exports = {
        entry: './src/app.js',
        output: {
            path: './bin',
            filename: 'app.bundle.js',
        },
        module: {
            loaders: [{
                test: /.jsx?$/,
                exclude: /node_modules/,
                loader: 'babel',
            }]
        },
        plugins: [
            new webpack.optimize.UglifyJsPlugin({
                compress: {
                    warnings: false,
                },
                output: {
                    comments: false,
                },
            }),
        ]
    }

    uglify 插件在webpack包中已经包含了,所以你不需要另外添加,但也有可能出现例外。你可以编写自己的自定义插件。在这个例子中, uglify 插件就把文件从1618b压缩到了308b。

  • 相关阅读:
    分布式搜索引擎Elasticsearch的查询与过滤
    剖析Elasticsearch集群系列第一篇 Elasticsearch的存储模型和读写操作
    分布式缓存 cachecloud
    npm是什么NPM的全称是Node Package Manager
    Grafana监控可视化环境搭建
    github ssl验证跳过
    Linux分区扩容
    手把手教你把Vim改装成一个IDE编程环境(图文)
    根据条件批量删除document
    奇智网络聊天机器人
  • 原文地址:https://www.cnblogs.com/WEI-web/p/6544123.html
Copyright © 2011-2022 走看看