webpack入门

一、模块化:

1、什么是模块化?

  就是将一个个文件看做一个个模块,模块之间互不影响,主要针对的是js文件。

2、为什么会产生模块化的思想?

原始的一个个js文件 都是在html中通过<script stc='xxx.js'>来引入,当js文件很多时会产生很多问题:

(1)、变量之间的污染冲突。

(2)、因为浏览器是按js文件引入的顺序加载,而且会在一些js文件使用了其他js文件的方法、变量或者调用引入插件方法等等,这些都需要我们人工调整加载顺序。

(3)、时间太长后,代码维护管理困难。

(4)、这样引入造成代码结构不清晰,冗余

所以就产生了模块化的思想,我们设置一个入门文件entry.js,通过module.exports 和 exports导出模块接口,通过require()导入模块,然后各个模块之间相互依赖调用,

最终我们在html文件中只需引入一个entry.js文件即可。

3、模块化实现基本原理:

每个模块中都存在三个自由变量require、module、exports,其中module和exports负责导出模块接口,require负责导入其他模块。

为了实现各个模块之间的独立,我们会将每个文件代码使用立即执行函数包裹,将三个自由变量当做参数传入。

module.export是一个对象,存储着该模块要导出的接口,且exports指向module.exports的 引用,我们为module.exports对象赋值或者添加属性,最后通过return返回导出接口。

其他模块通过require('filenamePath')方法引入获取模块接口,基本原理就是读取该模块文件代码然后执行,得到执行后的返回值即是该模块接口,为了避免每次执行,一般都会设置缓存机制。

4、模块化规范(CommomJs、AMD/CMD)

这些都是都是模块化开发的一些标准API。

注:js文件可以异步加载,但所有js文件的执行一定是同步,也就是串行的,这是由于js单线程的特点决定的。

(1)、CommonJs

CommonJs主要定义一的是服务器端的一些API,该模块是通过reqire同步记载模块(加载执行完一模块后,才继续下一个),然后通过moduel.exports或exports导出模块接口。

浏览器客户端要求 效率速度,一般都是异步加载资源,所以CommonJs不适用客户端。

CommonJs的主要实现是nodejs。

(2)、AMD/CMD

AMD和CMD也是模块化规范,和CommonJs不同的是,它们是异步加载模块,也就是在加载某个模块的时候,还可以并行加载其他模块并执行。

但是AMD和CMD也有一些区别:

  AMD是预加载,在加载js文件模块同时,还会解析执行该模、(正因为要执行,所以在加载某个模块前,该模块的所有依赖模块都要加载完毕,为该模块执行做准备)

    CMD是懒加载(按需加载),异步加载模块,但并不会执行,仅在需要时才执行。

优缺点:

  AMD因为一边加载一边执行,所以加载效率高,但是加载顺序不一定顺序不受控制。

  CMD加载顺序可控,但是因为模块不是提前执行完毕,且js执行时串行的,所以所需时间较长。

二、webpack介绍:

webpack是模块打包器,webpack从入口文件开始整个项目结构,找到JavaScript模块和一些浏览器不能直接识别运行的,按照指定规则将其打包为合适的格式到出口文件。

webpack是在其他模块打包管理工具的功能上发展出来的更具优势的工具。

三、webpack优点

(1)、webpack为我们提供了基于CommonJS模块化开发环境,可以直接使用CommonJS规范开发,webpack会将其打包为浏览器可识别运行的文件。

(2)、webpack本身只能处理JavaScript模块,但是我们通过loader转换器,将各种类型资源转换为JavaScript模块处理,这样来说,任何类型模块webpack都可以处理,

我们还可以使用浏览器不能识别的JavaScript语言新特性。

(3)、webpack可以检测js文件变化,自动将其打包为合适格式的出口文件。

(4)、webpack具有智能解析器,几乎可以处理任何第三方库。

(5)、丰富的插件系统,来满足各种需求。

(6)webpack会将代码分割生成很多文件,然后按需加载,而不是想传统打包工具将整个项目所有模块都打包生成一个很大的文件,导致加载很慢。

四、webpack使用:

使用前我们要安装nodejs,我们使用nodejs带npm来进行包管理。

1、安装:

(1)、执行命令全局安装webpack

npm install webpack -g

(2)、创建一个项目文件夹,在该文件下执行命令 ,一路回车,生成package.json,进行包管理

npm init

(3)、在该项目目录下执行命令本地安装:

npm install webpack --save-dev

(4)、执行命令安装开发工具,执行webpack-dev-server,会自动创建一个本地服务器,我们在浏览器输入localhost:8080/html的文件名(默认为index.html)可访问

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

2、简单用法:

在项目文件夹中创建index.html文件 和 entry.js文件,然后在index.html文件中使用<script src>引入bundle.js

我们在命令行的项目目录下执行 webpack entry.js bundle.js ,如果没有报错,访问该index.html文件即可看到index.js中代码执行的结果(这个测试代码随意)

语法是: wepack 入口文件路径 出口文件路径 [--module-bind '加载的loader']

后面的loader就是用来处理非js文件模块和浏览器不能识别的js新特性模块,使用前需要使用npm install下载,比如css-loader解析css模块的loader 

npm install css-loader --save-dev

3、配置文件:

我们将入口文件路径、出口文件路径、加载的loader、加载的插件等写到配置文件里,然后就省去了命令行的长命令,直接执行 webpack 即可打包。

var webpack = require('webpack');
// 声明全局变量
var providePlugin = new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery', 'window.jQuery': 'jquery' });
// common插件,一个模块被多个模块引用,为避免代码冗余,提取该模块 公共代码生成common.js文件,需要我们在html中手动引入
var commonsChunkPlugin = new webpack.optimize.CommonsChunkPlugin('common.js')


module.exports = {  // 入口文件设置 从index 的值(路径) 找到该文件  output的path则是 编译后文件输出的路径
    // entry可以是字符串、数组、对象,
    // 只有一个入口使用字符串
    // 添加多个互不相干的文件,使用数组格式,这些文件最终都会输出到一个文件中
    // 应用多页面,添加多个文件,使用对象形式,会为每个文件生成一个输出文件
    entry: {
        demo: './src/js/index.js'
    },
    //public 是 图片被转换成base64 后的路径
    output: {
        path: './static/dist/',
        // 用于生产模式下跟新内嵌到css和html文件里的url值
        publicPath: 'http://localhost:8080/static/dist/', 
        // 最终生成的文件名字,name会取自entry的键值
        filename: '[name].js'
    },
    // 代码中文件路径中可以省去这些后缀,自动检测
    resolve: {
        extends: ['.js', '.css', '.less']
    },
    // 加载器 从顶层文件夹开始寻找 找到匹配的文件 用依赖模块进行加载
    module: {
        loaders: [
            {
                test: /.js$/,
                loader: 'babel',
                // include 表示哪些目录中的 .js 文件需要进行 babel-loader
                // exclude 表示哪些目录中的 .js 文件不要进行 babel-loader
                exclude: /node_modules/,
                // 给babel-loader传参,两种方法:1、? 2、query
                query: {
                    // react解决jsx语法,es2015解决es6语法,所以就需要jsx.loader
                    presets: ['react', 'es2015']
                }
            },
            // { test: /.js$/, loader: 'jsx-loader?harmony' },
            // 使用exports-loader解决第三方类库的问题
            // 得到jquery模块的绝对路径 require.resolve('./src/js/tool/jquery')
            // exports-loader?jQuery 将jquery绑定为window.jQuery
            // {test: require.resolve('./src/js/tool/jquery'), loader: 'exports-loader?jQuery'},
            { test: /.css$/, loader: 'style-loader!css-loader' },
            { test: /.(png|jpg)$/, loader: 'url-loader?limit=8192' },
            { test: /.less$/, loader: 'style-loader!css-loader!less-loader' }]
    },
    plugins: [providePlugin, commonsChunkPlugin]
};


//cnpm install babel-loader babel-core babel-preset-es2015 babel-preset-react react react-dom
// cnpm webpack-dev-server --save-dev

4、开发调试:

 (1)一些命令技巧:

    一般的 webpack 一次性打包并不能满足我们的要求。

  我们可以使用 webpack -w 开启监听模式,没有变化的模块缓存到内存中,发生变化的模块重新编译。

  当然我们还可以使用 webpack-dev-server ,将会在localhost:8080启动一个express的http静态服务器,并以监听模式自动运行webpack,自动刷新页面,服务器默认当前目录为项目目录,我们输入正确的路径访问html文件即可。

  如果项目过大,编译时间较长,我们使用 --grogress --colors 让输出内容带有进度和颜色,如下:

webpack -w --progress --colors
webpack-dev-server --progress --colors

   (2)、使用npm测试命令:

我们可以在package.json中调整scripts选项,如下:

 参考:http://www.jianshu.com/p/dcb28b582318 、http://zhaoda.net/webpack-handbook/

---------------------------------------

原文地址:https://www.cnblogs.com/Walker-lyl/p/7294807.html