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。

  • 相关阅读:
    虚函数和纯虚函数
    MS CRM 2011中PartyList类型字段的实例化
    MS CRM 2011的自定义与开发(12)——表单脚本扩展开发(4)
    MS CRM 2011的自定义与开发(12)——表单脚本扩展开发(2)
    MS CRM 2011的自定义和开发(10)——CRM web服务介绍(第二部分)——IOrganizationService(二)
    MS CRM 2011 SDK 5.08已经发布
    MS CRM 2011 Q2的一些更新
    最近很忙
    Microsoft Dynamics CRM 2011最近的一些更新
    补一篇,Update Rollup 12 终于发布了
  • 原文地址:https://www.cnblogs.com/WEI-web/p/6544123.html
Copyright © 2011-2022 走看看