webpack简介及webpack.config.js的配置


基本信息:

// webpack在执行时,除在命令行传入参数,还可以通过指定的配置文件来执行。默认会搜索当前目录下webpack.config.js。
// 这个文件是一个node.js模块,返回一个json格式的配置对象,或者通过--config选项来指定配置文件。
var webpack = require('webpack');
module.exports = {
  entry:'./entry.js',  //入口文件
  // entry可以是个字符串或数组或者是对象。
// 当entry是个字符串的时候,用来定义入口文件:
// 当entry是个数组的时候,里面同样包含入口js文件,另外一个参数可以是用来配置webpack提供的一个静态资源服务器
// ,webpack-dev-server。webpack-dev-server会监控项目中每一个文件的变化,实时的进行构建,并且自动刷新页面:
// entry: [
//      'webpack/hot/only-dev-server',
//      './js/app.js'
// ]
  output:{
    //node.js中__dirname变量获取当前模块文件所在目录的完整绝对路径
    path:__dirname, //输出位置
    filename:'build.js' //输入文件
  },
  // output参数是个对象,用于定义构建后的文件的输出。其中包含path和filename


  module:{  //关于模块的加载相关,我们就定义在module.loaders中。这里通过正则表达式去匹配不同后缀的文件名
    // ,然后给它们定义不同的加载器。比如说给less文件定义串联的三个加载器(!用来定义级联关系):
    // loaders: [
    //     { test: /\.js?$/, loaders: ['react-hot', 'babel'], exclude: /node_modules/ },
    //     { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader'},
    //     { test: /\.css$/, loader: "style!css" },
    //     { test: /\.less/, loader: 'style-loader!css-loader!less-loader'}
    // ]
    loaders:[
      {
        test:/\.css$/,      //支持正则
        loader:'style-loader!css-loader'
      }
    ]
  },
  //其他解决方案配置
  resolve:{ //webpack在构建包的时候会按目录的进行文件的查找,
    // resolve属性中的extensions数组中用于配置程序可以自行补全哪些文件后缀
    extensions:['','.js','.json','.css','.scss']   //添加在此的后缀所对应的文件可省略后缀,
    // 然后我们想要加载一个js文件时,只要require(‘common’)就可以加载common.js文件了。
  },
  //插件
  plugins:[
    new webpack.BannerPlugin('This file is create by baibai')
  ]

//   当我们想在项目中require一些其他的类库或者API,而又不想让这些类库的源码被构建到运行时文件中,
// 这在实际开发中很有必要。此时我们就可以通过配置externals参数来解决这个问题:
//
//  externals: {
//      "jquery": "jQuery"
//  }
//
//
// 这样我们就可以放心的在项目中使用这些API了:var jQuery = require(“jquery”);
}

例子的webpack.config.js:

var htmlWebpackPlugin=require('html-webpack-plugin');//自动生成html文件
var path=require('path');//path是内置的
var WebpackDevServer = require('webpack-dev-server');//自动刷新模块

//对外暴露一个对象
module.exports={
    // entry:__dirname +"/app/index.js",//打包的入口文件 对象或字符串
    entry:{//打包多个入口文件
        build:__dirname+"/es6/index.js"
    },
    output:{//配置打包结果 对象
        path:__dirname +"/es6_build/",//定义输出文件路径
        // filename:"build.js",//指定打包文件名称
        filename:"[name].js"//指定多个打包文件名称
    },
    module:{//对文件的处理逻辑 数组
        loaders:[//加载器是数组,数组中的每一项是一个对象
            {
                test:/.css$/,//是一个正则,处理后缀名为css的文件,匹配到的文件名后缀
                // webpack在打包过程中,遇到后缀为css的文件,就会使用style-loader和css-loader去加载这个文件。
                loaders:["style-loader","css-loader"],//放加载器,一个是字符串,两个就写成数组
                // 最后计算完的css,将会使用style-loader生成一个内容为最终解析完的css代码的style标签,放到head标签里。
                // 需要注意的是,loader是有顺序的,webpack肯定是先将所有css模块依赖解析完得到计算结果再创建style标签。
                // 因此应该把style-loader放在css-loader的前面(webpack loader的执行顺序是从右到左)。
                exclude:"/node_modules"//要排除的文件夹
            },
            {
                test:/.js$/,
                loaders: ["babel-loader"], //将es6代码转换为es5代码
                exclude:"/node_modules",
                include:path.resolve(__dirname,"/es6/")//要包含的文件
            }
        ]
    },
    devServer:{//配置服务
        hot:true, //启用热模块替换
        inline:true //自动刷新页面时使用inline模式(将webpack-dev-sever的客户端入口添加到包(bundle)中)
        //此模式支持热模块替换:热模块替换的好处是只替换更新的部分,而不是页面重载.
    },
    resolve:{
        extensions:[' ','.js','.css','.jsx'] //自动补全识别后缀名
    },
    plugins:[
      // 插件可以完成更多loader不能完成的功能。插件的使用一般是在webpack.config.js中的plugins 选项中指定。
      // Webpack本身内置了一些常用的插件,还可以通过npm安装第三方插件。
        new htmlWebpackPlugin({//自动生成html文件
            title:"欢迎",//title标签为欢迎这个字符串
            chunks:["build"] //引用的模块(abc.js)
        }),
        new webpack.HotModuleReplacementPlugin()  //启用热模块替换
    ]
}

babel原理:

babel是一个转译器,感觉相对于编译器compiler,叫转译器transpiler更准确,因为它只是把同种语言的高版本规则翻译成低版本规则,而不像编译器那样,输出的是另一种更低级的语言代码。
但是和编译器类似,babel的转译过程也分为三个阶段:parsing(解析)、transforming(转换)、generating(产生),以ES6代码转译为ES5代码为例,babel转译的具体过程如下:

ES6代码输入 ==》 babylon进行解析 ==》 得到AST
==》 plugin用babel-traverse对AST树进行遍历转译 ==》 得到新的AST树
==》 用babel-generator通过AST树生成ES5代码

此外,还要注意很重要的一点就是,babel只是转译新标准引入的语法,比如ES6的箭头函数转译成ES5的函数;而新标准引入的新的原生对象,部分原生对象新增的原型方法,新增的API等(如Proxy、Set等),这些babel是不会转译的。需要用户自行引入polyfill来解决。

babel会从当前转译的文件所在目录下查找配置文件,如果没有找到,就顺着文档目录树一层层往上查找,一直到.babelrc文件存在或者带babel字段的package.json文件存在为止。

.babelrc文件:

{"presets":["es2015"]} //presets是官方预设的插件集,es2015是其中一个

热加载:

模块热替换(HMR - Hot Module Replacement)功能会在应用程序运行过程中替换、添加或删除模块,而无需重新加载整个页面。主要是通过以下几种方式,来显著加快开发速度:

  • 保留在完全重新加载页面时丢失的应用程序状态。
  • 只更新变更内容,以节省宝贵的开发时间。
  • 调整样式更加快速 - 几乎相当于在浏览器调试器中更改样式。

在开发过程中,可以将 HMR 作为 LiveReload 的替代。webpack-dev-server 支持 hot 模式,在试图重新加载整个页面之前,热模式会尝试使用 HMR 来更新。

实现原理:

在应用程序中:

通过以下步骤,可以做到在应用程序中置换(swap in and out)模块:

  1. 应用程序代码要求 HMR runtime 检查更新。
  2. HMR runtime(异步)下载更新,然后通知应用程序代码。
  3. 应用程序代码要求 HMR runtime 应用更新。
  4. HMR runtime(异步)应用更新。

你可以设置 HMR,以使此进程自动触发更新,或者你可以选择要求在用户交互时进行更新。

在编译器中:

除了普通资源,编译器(compiler)需要发出 "update",以允许更新之前的版本到新的版本。"update" 由两部分组成:

  1. 更新后的 manifest(JSON)
  2. 一个或多个更新后的 chunk (JavaScript)

manifest 包括新的编译 hash 和所有的待更新 chunk 目录。每个更新 chunk 都含有对应于此 chunk 的全部更新模块(或一个 flag 用于表明此模块要被移除)的代码。

编译器确保模块 ID 和 chunk ID 在这些构建之间保持一致。通常将这些 ID 存储在内存中(例如,使用 webpack-dev-server 时),但是也可能将它们存储在一个 JSON 文件中。

在模块中:

HMR 是可选功能,只会影响包含 HMR 代码的模块。举个例子,通过 style-loader 为 style 样式追加补丁。 为了运行追加补丁,style-loader 实现了 HMR 接口;当它通过 HMR 接收到更新,它会使用新的样式替换旧的样式。

类似的,当在一个模块中实现了 HMR 接口,你可以描述出当模块被更新后发生了什么。然而在多数情况下,不需要强制在每个模块中写入 HMR 代码。如果一个模块没有 HMR 处理函数,更新就会冒泡。这意味着一个简单的处理函数能够对整个模块树(complete module tree)进行更新。如果在这个模块树中,一个单独的模块被更新,那么整组依赖模块都会被重新加载。


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值