webpack初体验

青春壹個敷衍的年華 提交于 2020-04-29 17:31:55

Webpack最近貌似很火啊,所以挤空学习掌握了一下,主要最近打算做个自己的网站,后端用node+mongodb,所以没什么时间

 

Webpack是一个模块打包器。它将根据模块的依赖关系进行静态的分析,然后将这些模块按照指定的规则生成对应的静态资源。

 

虽然市面上已经有很多模块管理工具和打包工具,gulp啊,grunt啊种种。但是这些已有的模块化工具并不能很好的完成如下的目标:

  • 将依赖树拆分成按需加载的块
  • 初始化加载的耗时尽量少
  • 各种静态资源都可以视为模块
  • 将第三方库整合成模块的能力
  • 可以自定义大包逻辑的能力
  • 适合大项目,无论是单页面或者多页面的web应用

 

Webpack的特点以及优势:

  1. 代码拆分:webpack有两种组织模块依赖的方式,同步和异步。异步依赖作为分割点,形成一个新的块。在优化了依赖树后,每一个异步区块都作为一个文件被打包
  2. Loader:wp本身只能处理原生js模块,但loader转换器可以将各种类型的资源转换成js模块,这样,任何资源都可以成为wp可以处理的模块。
  3. 智能分析:wp有一个智能分析器,基弧可以处理任何第三方库无论他们的模块形式是CommonJS,AMD还是普通的js文件。甚至在加载依赖的时候,允许使用动态表达式require(“./teplates/“+name+”.jade”);
  4. 插件系统:wp还有一个功能丰富的插件系统。大多数内容功能都是可以基于这个插件系统运行的,还可以开发和使用开源的wp插件,来满足各式各样的需求
  5. 快速运行:wp使用异步I/O和多级缓存提高运行效率,这使得wp能够以令人难以执行的速度快速增量编译。

安装和使用

webpack的安装首先需要Node.js,因为node自带了软件包管理器nam,wp需要node v0.6以上的支持,当然,这个我们最好是使用最新版稳定的node

用nam安装wp:nam install -g webpack

此时,wp已经安装到全局环境下了,可以通过webpack -h试试

然后在项目中安装wp:

这个和gulp很类似啊,全局安装一个,项目中也需要安装下.

wp目前有两个主版本,一个是在master主干的稳定版,一个是在webpack-2分支的测试版,测试版拥有一些实验性功能并且和稳定版不兼容,在正式项目中应该使用稳定版。

通过 npm info webpack来查看当前wp的信息

然后安装制定的版本的webpack

然后在我们的项目中新建一个index.html,在index.html中引入bundle.js,在新建一个entry.js

运行 webpack entry.js bundle.js

 回生成如下的bundle.js文件:

下面我们把一些代码移到我们新建的content.js中,然后修改entry.js文件里的内容如下:

/**
 * Created by Nealyang on 16/10/24.
 */
// document.write('it works');
document.write(require('./content'));

content.js文件内容如下:

/**
 * Created by Nealyang on 16/10/24.
 */
module.exports = 'It works from  contenetJs';

 

运行命令:

webpack ./entry.js bundle.js

 

结果我想大家都应该可以想到,可以自己试一试。

wp会分析入口文件,解析包依赖关系的各个文件,这些文件或者模块都打包到bundle.js。wp会给每一个模块分配一个唯一的id并通过id来索引和访问模块。在页面启动的时候会执行entry.js中的代码,其他的模块会运行require的时候再执行。

Loader介绍

wp本身只能处理js模块,如果要处理其它类型的文件,就需要使用loader进行转换

loader可以理解为是模块和资源的转换器,它本身就是一个函数,接受源文件作为参数,转返回转换后的结果。这样我们可以通过require来加载任何类型的模块和文件,比如coffeescript,jsx,less或者图片

先看看Loader有哪些特点:

  • Loader可以通过管道方式链式调用(这一点和gulp非常的累死)每一个Loader可以把资源转换成任意格式并传递给下一个Loader,但是最后一个Loader必须返回js。
  • Loader可以同步或者异步
  • Loader运行在nodejs的环境中,所以可以做任何可能的事情
  • Loader可以接受参数,以此来传递配置项给Loader
  • Loader可以通过文件扩展名或者正则表达式绑定给不同类型的文件
  • Loader可以通过npm安装和发布
  • 除了通过package.json的main指定,通常的模块也可以导出一个Loader来使用
  • Loader可以访问配置
  • 插件可以让Loader拥有更多的特性
  • Loader可以分发出附件的任意文件

Loader简单的实例:加载css文件

首先安装loader :npm install css-loader style-loader

注意这里安装loders只需要安装本地的,不要全局的,并且它会创建一个node_modules文件夹。

 

  我们添加一个style.css文件:

 

body{
    background-color: red;
}

 

然后在entry中添加一行:

/**
 * Created by Nealyang on 16/10/24.
 */
// document.write('it works');
require("!style!css!./style.css");
document.write(require('./content'));

最后重新编译。。。

就可以看到背景颜色已经修改为红色了

 

如果每一次require css文件都要写loader前缀,是一件非常繁琐的事情。

所以我们可以根据模块类型来自动绑定需要的loader这样写

require(“./style.css”);

修改entry.js文件

/**
 * Created by Nealyang on 16/10/24.
 */
// document.write('it works');
// require("!style!css!./style.css");
require("./style.css");
document.write(require('./content'));

编译:

webpack ./entry.js bundle.js --module-bind "css=style!css"

注意:!在shell中有特殊意义,需要转义,这样写才会成功的

webpack ./entry.js bundle.js --module-bind "css=style\!css"

当然,这两种方式,效果是一样的

 

配置文件

webpack在执行的时候除了可以在命令行中传入参数,还可以通过制定的配置文件来执行。默认情况下,会搜索当前目录的webpack.config.js文件,这个文件是一个node.js模块,返回一个json格式的配置信息对象,或者通过—cofnig选项来置顶配置文件。

我们想将配置选项移动到配置文件中,创建一个webpack.config.js

/**
 * Created by Nealyang on 16/10/24.
 */
module.exports = {
    entry: "./entry.js",
    output: {
        path: __dirname,
        filename: "bundle.js"
    },
    module: {
        loaders: [
            { test: /\.css$/, loader: "style!css" }
        ]
    }
};

现在我们仅仅运行:webpack

这里对Webpack的打包行为做了配置,主要分为几个部分:

  • entry:指定打包的入口文件,每有一个键值对,就是一个入口文件
  • output:配置打包结果,path定义了输出的文件夹,filename则定义了打包结果文件的名称
  • module:定义了对模块的处理逻辑,这里可以用loaders定义了一系列的加载器,以及一些正则。当需要加载的文件匹配test的正则时,就会调用后面的loader对文件进行处理,这正是webpack强大的原因。

如果该项目的增长,编译可能需要更长的时间。所以我们要展示一些进度条。我们想要的颜色…

 

我们可以这样

webpack--progress--colors

 

插件可以完成更多 loader 不能完成的功能。

插件的使用一般是在 webpack 的配置信息 plugins 选项中指定。

Webpack 本身内置了一些常用的插件,还可以通过 npm 安装第三方插件。

接下来,我们利用一个最简单的 BannerPlugin 内置插件来实践插件的配置和运行,这个插件的作用是给输出的文件头部添加注释信息。

 

修改 webpack.config.js,添加 plugins

var webpack = require('webpack');

module.exports = {

entry: './entry.js',

output: {

path: __dirname,

filename: 'bundle.js'

},

module: {

loaders: [

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

]

},

plugins: [

new webpack.BannerPlugin('This file is created by mutouren')

]

}

 

然后运行 webpack,打开 bundle.js,可以看到文件头部出现了我们指定的注释信息

模块别名定义,方便后续直接引用别名,无须多写长长的地址,比如我们现在想要把scripts/jquery.min.jsjquery压缩文件打包.

 

别名(resolve.alias) 是 Webpack 的一个配置项,它的作用是把用户的一个请求重定向到另一个路径,例如通过修改 webpack.config.js 配置文件,jquery为别名加入

resolve: {

alias: {

jquery: "./scripts/jquery.min.js"

}

}

例如我们之前不用别名,在entry.js中,想要把jquery打包

require('./scripts/jquery.min.js');

设置别名,就可以修改为

require('jquery');

这样待打包的脚本中的 require('jquery'); 其实就等价于 require('./scripts/jquery.min.js'); 。通过别名的使用在本例中可以减少几乎一半的时间。

 

我们把需要的jquery打包了,但是现在前台页面想要直接用还是不可以的,需要我们把jquery暴露出来。

 

你可能在全局中使用了一个压缩版本的 jquery,为了修复你可以安装这个暴露全局加载器

npm install expose-loader --save-dev

然后像下面这样修改entry.js

require('expose?$!jquery');

$作为别名为jquery的变量暴露到全局上下文中。

 

现在我们在页面就可以使用$,例如:

$('h1').text();

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!