Webpack 学习总结

1.Webpack的特性

webpack 模块打包机,分析你的项目结构,找到JavaScript模块以及其他一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),将其打包为合适的格式以供浏览器使用。

webpack具有requireJs和browserify的功能,但仍有很多自己的新特性:

1. 对 CommonJS 、 AMD 、ES6的语法做了兼容

2. 对js、css、图片等资源文件都支持打包

3. 串联式模块加载器以及插件机制,让其具有更好的灵活性和扩展性,例如提供对CoffeeScript、ES6的支持

4. 有独立的配置文件webpack.config.js

5. 可以将代码切割成不同的chunk,实现按需加载,降低了初始化时间

6. 支持 SourceUrls 和 SourceMaps,易于调试

7. 具有强大的Plugin接口,大多是内部插件,使用起来比较灵活

8.webpack 使用异步 IO 并具有多级缓存。这使得 webpack 很快且在增量编译上更加快

Webpack和Grunt, Gulp的区别:

Grunt和Gulp的工作方式是:在一个配置文件中,指明对某些文件进行类似编译,组合,压缩等任务的具体步骤,然后这个工具自动替你完成这些任务。(Do a series of tasks)

Webpack的工作方式是,把项目当做一个整体,通过给定一个主文件entry(index.js),Webpack 将从这个文件开始找到项目的所有依赖文件,使用loaders处理他们,最后打包为浏览器可识别的JavaScript文件。(从入口文件查找下载依赖) 效率更高,打包更好。

2.开始使用Webpack

webpack 可以作为全局的npm模块安装,也可以在当前项目中安装。

npm install -g webpack

npm install --save-dev webpack

在终端的最基础命令:webpack {entry file/入口文件} {destination for bundled file/存放bundle.js的地方}   只需要一个入口文件,webpack将自动识别项目所依赖的其他文件。

如果是非全局安装,直接在命令行下执行 node_modules/.bin/webpack,就会自动读取webpack.config.js文件中的配置,输出打包后的文件。

在项目的package.son 文件中配置,实现快速打包:

{
  "name": "webpack-sample-project",
  "version": "1.0.0",
  "description": "Sample webpack project",
  "scripts": {
    "start": "webpack"      //配置的地方就是这里啦,相当于把npm的start命令指向webpack命令
  },
  "author": “dd”,
  "license": "ISC",
  "devDependencies": {
    "webpack": "^1.13.2",
  }
}

在项目中通过配置webpack.config.js 文件来使用Webpack, Webpack的强大功能都体现在配置文件中。下面是一个基本配置示例:

var path = require(‘path‘);

module.exports = {
    entry: path.resolve(__dirname, ‘./src/index.js‘), //已多次提及的唯一入口文件

    output: {
        path: path.resolve(__dirname, ‘./bundle‘), //打包后的文件存放的地方

        filename: ‘bundle.js‘   //打包后输出文件的文件名

    },

    module: {
        loaders: [
            { test: /\.js?$/, loaders: [‘babel‘], exclude: /node_modules/ },
            { test: /\.js$/, loader: ‘babel-loader‘, exclude: /node_modules/}
        ]
    },

    resolve:{
        extensions:[‘‘,‘.js‘,‘.json‘]
    },
};

注:“__dirname”是node.js中的一个全局变量,它指向当前执行脚本所在的目录。

(1)entry

entry参数定义了打包后的入口文件,可以是个字符串或数组或者是对象;如果是数组,数组中的所有文件会打包生成一个filename文件;如果是对象,可以将不同的文件构建成不同的文件。

{

    entry: {

        page1: "./page1",

        //支持数组形式,将加载数组中的所有模块,但以最后一个模块作为输出

        page2: ["./entry1", "./entry2"]

    },

    output: {

        path: "dist/js/page",

        publicPath: "/output/",

        filename: "[name].bundle.js"

    }

}

该段代码最终会生成一个 page1.bundle.js 和 page2.bundle.js,并存放到 ./dist/js/page 文件夹下

(2)output

output参数是个对象,定义了输出文件的位置及名字:

output: {

        path: "dist/js/page",

        publicPath: "/output/",

        filename: "[name].bundle.js"

    }

path: 打包文件存放的绝对路径

publicPath: 网站运行时的访问路径

filename:打包后的文件名

当我们在entry中定义构建多个文件时,filename可以对应的更改为[name].js用于定义不同文件构建后的名字。

(3)module

module: {

        //加载器配置

        loaders: [

            //.css 文件使用 style-loader 和 css-loader 来处理

            { test: /\.css$/, loader: ‘style-loader!css-loader‘ },

            //.js 文件使用 jsx-loader 来编译处理

            { test: /\.js$/, loader: ‘jsx-loader?harmony‘ },

            //.scss 文件使用 style-loader、css-loader 和 sass-loader 来编译处理

            { test: /\.scss$/, loader: ‘style!css!sass?sourceMap‘},

            //图片文件使用 url-loader 来处理,小于8kb的直接转为base64

            { test: /\.(png|jpg)$/, loader: ‘url-loader?limit=8192‘}

        ]

    }

在webpack中JavaScript,CSS,LESS,TypeScript,JSX,CoffeeScript,图片等静态文件都是模块,不同模块的加载是通过模块加载器(webpack-loader)来统一管理的。loaders之间是可以串联的,一个加载器的输出可以作为下一个加载器的输入,最终返回到JavaScript上。

(4)resolve

webpack在构建包的时候会按目录的进行文件的查找,resolve属性中的extensions数组中用于配置程序可以自行补全哪些文件后缀:

resolve: {

        //查找module的话从这里开始查找

        root: ‘/pomy/github/flux-example/src‘, //绝对路径

        //自动扩展文件后缀名,意味着我们require模块可以省略不写后缀名

        extensions: [‘‘, ‘.js‘, ‘.json‘, ‘.scss‘],

        //模块别名定义,方便后续直接引用别名,无须多写长长的地址

        alias: {

            AppStore : ‘js/stores/AppStores.js‘,//后续直接 require(‘AppStore‘) 即可

            ActionType : ‘js/actions/ActionType.js‘,

            AppAction : ‘js/actions/AppAction.js‘

        }

    }

然后我们想要加载一个js文件时,只要require(‘common‘)就可以加载common.js文件了。

注意一下, extensions 第一个是空字符串 ‘‘ 对应不需要后缀的情况.

(5)externals

当我们想在项目中require一些其他的类库或者API,而又不想让这些类库的源码被构建到运行时文件中,这在实际开发中很有必要。此时我们就可以通过配置externals参数来解决这个问题:

externals: {

"jquery": "jQuery"

}

(6)devtool使调试变得更容易

devtool选项           配置结果

source-map: 在一个单独的文件中产生一个完整且功能完全的文件。这个文件具有最好的source map,但是它会减慢打包文件的构建速度;

cheap-module-source-map: 在一个单独的文件中生成一个不带列映射的map,不带列映射提高项目构建速度,但是也使得浏览器开发者工具只能对应到具体的行,不能对应到具体的列(符号),会对调试造成不便;

eval-source-map: 使用eval打包源文件模块,在同一个文件中生成干净的完整的source map。这个选项可以在不影响构建速度的前提下生成完整的sourcemap,但是对打包后输出的JS文件的执行具有性能和安全的隐患。不过在开发阶段这是一个非常好的选项,但是在生产阶段一定不要用这个选项;

cheap-module-eval-source-map: 这是在打包文件时最快的生成source map的方法,生成的Source Map. 会和打包后的JavaScript文件同行显示,没有列映射,和eval-source-map选项具有相似的缺点;

(7)devServer 构建本地服务器

contentBase: 默认webpack-dev-server会为根文件夹提供本地服务器, 如果想为另外一个目录下的文件提供本地服务器,应该在这里设置其所在目录

port: 设置默认监听端口,如果省略,默认为”8080“

inline: 设置为true,当源文件改变时会自动刷新页面

colors: 设置为true,使终端输出的文件为彩色的

historyApiFallback: 在开发单页应用时非常有用,它依赖于HTML5 history API,如果设置为true,所有的跳转将指向index.html

(8)loader配置

通过使用不同的loader,webpack通过调用外部的脚本或工具可以对各种各样的格式的文件进行处理,

比如说分析JSON文件并把它转换为JavaScript文件,或者说把下一代的JS文件(ES6,ES7)转换为现代浏览器可以识别的JS文件。

或者说对React的开发而言,合适的Loaders可以把React的JSX文件转换为JS文件。

Loaders需要单独安装并且需要在webpack.config.js下的modules关键字下进行配置,

Loaders的配置选项包括以下几方面:

test:一个匹配loaders所处理的文件的拓展名的正则表达式(必须)

loader:loader的名称(必须)

include/exclude:手动添加必须处理的文件(文件夹)或屏蔽不需要处理的文件(文件夹)(可选);

query:为loaders提供额外的设置选项(可选)

安装babel,babel具有非常多的配置选项,在单一的webpack.config.js文件中进行配置往往使得这个文件显得太复杂,因此一些开发者支持把babel的配置选项放在一个单独的名为 ".babelrc" 的配置文件中。如果不复杂,可以直接在webpack.config.js中进行配置。

{

      test: /\.jsx?$/,

      exclude: /node_modules/,

      loader: ‘babel-loader‘,

      options: {

        cacheDirectory: true,

        presets: [‘env‘, ‘stage-2‘, ‘react‘],

        plugins: [‘transform-runtime‘],

      },

   }

css Loader处理:

 test: /\.(less|css)$/,

  use: [

    {

      loader: ‘style-loader‘,

    },

    {

      loader: ‘css-loader‘,

      options: {

        minimize: false,

        sourceMap: true,

      },

    },

    {

      loader: ‘postcss-loader‘,

      options: {

        plugins: postcss, //自动添加适应不同浏览器的前缀

      },

    },

    {

      loader: ‘less-loader‘,

      options: {

        sourceMap: true,

      },

    },

  ]

npm一次性安装多个依赖模块,模块之间用空格隔开,安装babel 常用的依赖

npm install --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-react

(9)plugins

const plugins = [

  // plugin for passing in data to the js, like what NODE_ENV we are in.

  new webpack.DefinePlugin(config.globals),

  new webpack.optimize.CommonsChunkPlugin({

    names: [‘common‘, ‘vendor‘, ‘manifest‘],

    minChunks: 2,

  }),

  new webpack.NoEmitOnErrorsPlugin(),

//Hot Module Replacement(HMR)也是webpack里很有用的一个插件,它允许你在修改组件代码后,自动刷新实时预览修改后的效果。在webpack中实现HMR也很简单,只需要做两项配置。
/**在webpack配置文件中添加HMR插件,在Webpack Dev Server中添加“hot”参数;
      devServer: {

             hot: true

       }
*/

  new webpack.HotModuleReplacementPlugin(),

/**在入口文件中index.js中:

if (module.hot) {

 module.hot.accept(‘./home.js’); //接收这个文件的修改用来热加载

  module.hot.accept(‘./routes‘, () => {  //路由的改变将造成热加载,重新渲染

    render(createRouter)

  })

}
*/

  new webpack.NamedModulesPlugin(),

//HtmlWebpackPlugin 这个插件的作用是依据一个简单的模板(index.template.html),//帮你生成最终的Html5文件,这个文件中自动引用了你打包后的JS文件。每次编译都在文件名中插入一个不同的哈希值。
  new HtmlWebpackPlugin({

    title: ‘ACTIVE Reader Cloud Dev‘,

    inject: true,

    chunksSortMode: ‘dependency‘,

    filename: ‘index.html‘,

    template: paths.base(‘build/index.template.html‘),

  })

]

在package.json文件中:

devDependencies  里面的插件只用于开发环境,不用于生产环境,而 dependencies  是需要发布到生产环境的,安装的时候注意控制。

3.Webpack3的新特性

6月20日发布了webpack3, 它和2有什么区别?

(1)更新方法以及版本迁移

通过命令直接安装即可,后面需要加上版本号。

npm install [email protected] --save-dev

2)scope hoisting

webpack2处理后的每个模块均被一个函数包裹,如下:

/* 50 */

/***/ (function(module, __webpack_exports__, __webpack_require__) {

    window.lib = {}

    ...   

/* harmony default export */ __webpack_exports__["a"] = (window.lib);

/***/ }),

这样会带来一个问题:降低浏览器中JS执行效率,这主要是闭包函数降低了JS引擎解析速度。

于是webpack团队参考Closure Compiler和Rollup JS,将一些有联系的模块,放到一个闭包函数里面去,通过减少闭包函数数量从而加快JS的执行速度。

webpack3通过设置ModuleConcatenationPlugin使用这个新特性:

module.exports = { 

  plugins: [

    new webpack.optimize.ModuleConcatenationPlugin()

  ]

};

(3)Magic Comments

用于动态引入ES Module,webpack将传入import方法的模块打包到一个单独的代码块(chunk),但是却不能像require.ensure一样,为生成的chunk指定chunkName,因此在webpack3中提出了Magic Comment用于解决该问题,用法如下:

import(/* webpackChunkName: "my-chunk-name" */ ‘module‘);

其实就是可以命令 chunk name 了.

Webpack接下来的还会持续有的新特性:

  • 更好的编译缓存
  • 更快的首次以及增量编译速度
  • 对 TypeScript 更加友好地支持
  • 修改 Long term caching
  • 增加对 WASM Module 的支持
  • 用户体验的改进

小伙伴们敬请期待吧...

时间: 2024-10-03 08:48:43

Webpack 学习总结的相关文章

webpack学习笔记一

webpack.gulp.grunt是前端打包功能工具:因为已经学习了gulp,而最近发现webpack很火,于是着手学习webpack.本篇是webpack学习笔记系列的第一篇,欢迎指教. 我是从慕课网以及官网文档相结合的方式学习的,从官方文档学到的第一个知识点是在使用webpack打包过程中,即使没有webpack.config,js这个文件也是可以的. 首先是全局安装webpack,cmd(如果是window系统,在任意位置)执行命令: npm install --g webpack或cn

webpack学习笔记八

webpack自动刷新浏览器 webpack开发服务器,是webpack官方提供的一个辅助开发工具,它可以自动监控项目下的文件,一旦有修改保存的操作,它就会自动执行打包命令,将我们的代码重新打包,并且需要的话还可以刷新浏览器. 首先我们安装webpack-dev-server 在CMD中安装执行npm intall webpack-dev-server -g 在项目目录执行安装依赖命令: npm install --save-dev webpack-dev-server 其中webpack-de

webpack学习笔记

webpack笔记 webpack学习笔记 1.全局安装 npm install webpack -g 2.作为项目依赖安装 npm install webpack --save-dev 3.安装css-loader.sass-loader.node-scss npm install css-loader sass-loader node-scss --save-dev 4.webpack配置 // webpack.config.js var path = require('path'); mo

webpack学习(五)—webpack+react+es6

如果你看过webpack学习系列的前一个文章,接下来做的东西会比较简单 :webpack学习(四)- webpack-dev-server react发展的很快,现在大部分开发react相关的项目,都会用到这个组合:webpack+react+es6 还是以一个项目举例,项目中的package.json是生成的,"devDependencies"都是自己安装加入,如果拷贝网上的资料,可以npm install直接生成.而为了一探react的具体开发流程,还是自己一个个安装比较好. 项目

前端小白webpack学习(一)

俗话说得好,好记性不如烂笔头. 之前就在学习中看过webpack的教程,然而一段时间没用,火速的忘光了.写这篇博文,做个总结,也让自己以后有个地方回顾. 看webpack之前,我先去看了一下官方文档,先了解一下webpack的几个概念.我是中英文文档搀着看的,一些小地方中文文档里没写,英文文档里都给了小提示.(下面的概念是我自己翻译总计的,略渣) concepts At its core, webpack is a static module bundler for modern JavaScr

webpack学习记录(十二)-区分不同环境

webpack学习记录(十二)-区分不同环境 定义全局变量 使用webpack内置的插件DefinePlugin 允许创建一个在编译时可以配置的全局常量. 用法 //在webpack.config.js中配置插件 new webpack.DefinePlugin({ PRODUCTION: JSON.stringify(true) }) //在index.js中使用定义的变量 if (!PRODUCTION) { console.log('Debug info') } if (PRODUCTIO

webpack学习记录(九)-小插件应用

webpack学习记录(九)-小插件应用 clean-webpack-plugin 每次输出之前先删除之前的目录,即每次输出都是最新的打包文件 安装及配置 npm i clean-webpack-plugin -D // 注意该插件引入方式需要用解构赋值才有效 const {CleanWebpackPlugin} = require('clean-webpack-plugin') module.exports = { plugins: [ new CleanWebpackPlugin() ] }

webpack学习记录(十)-跨域

webpack学习记录(十)-跨域 准备工作 建一个简单的服务端 const express = require('express') let app = express() app.get('/api/user', (req,res) => { res.json({msg:'服务器启动'}) ) app.listen(3000) 发送一个请求 let xhr = new XMLHttpRequest() xhr.open('get','/api/user',true) xhr.onload =

webpack 学习

我的 webpack.config.js module.exports = { entry: [ './src/js/app.js', './src/js/my.js' ], output: { path: __dirname + '/output/', publicPath: "/output/", filename: 'main.js' }, module: { loaders: [ {test: /\.(jpg|png)$/, loader: "url?limit=81

webpack 学习心得(一)

Webpack 是一个模块打包器.它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源. 因为本人也正在学习webpack ,所以此篇文章比较入门. 首先你想使用webpack 需要安装node,推荐最好使用的是4.0以上(为了避免依赖安装错误) npm install -g webpack 安装 webpack 你可以手动创建相应文件,也可以这样 mkdir webpackdemo cd webpackdemo 创建 webpackdemo 文件夹 进入当前目录