前端模块化工具-webpack

时间:2021-07-26 03:52:59

webpack是一个模块管理工具,它跟grunt,gulp,fis等诸多前端工具一样,为了使日渐增多的js代码变得合理有序,应运而生的模块化工具

1 - 它同时支持commonjs和AMD规范(甚至混合的形式);
2 - 它可以打成一个完整的包,也可以分成多个部分,在运行时异步加载(可以减少第一次加载的时间);
3 - 依赖在编译时即处理完毕,可以减少运行时包的大小;
4 - Loaders可以使文件在编译时得到预处理,这可以帮我们做很多事情,比如说模板的预编译,图片的base64处理;
5 - 丰富的和可扩展的插件可以适应多变的需求。

下面是我的webpack的配置:

var webpack = require('webpack');
var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('common.js');
module.exports = {
    //插件项
    plugins: [commonsPlugin],
    //页面入口文件配置
    entry: {
        index : './app/js/index.js'
    },
    //入口文件输出配置
    output: {
        path: 'dist/js',
        filename: '[name].js'
    },
    module: {
    //加载器配置
        loaders: [
            { test: /\.css$/, loader: 'style-loader!css-loader'},
            { test: /\.jsx?$/, loader: 'babel',exclude: /node_modules/,query: {presets: ['es2015','react']}},
            { test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192'}
        ]
    },
    //其它解决方案配置
    resolve: {
        root: 'E:/react/app', //绝对路径
        extensions: ['', '.js','css'],
        alias: {
            ReactDom : 'react-dom.js'
        }
    }
};

 

webpack.config.js文件通常放在项目的根目录中,它本身也是一个标准的Commonjs规范的模块。在导出的配置对象中有几个关键的参数:

 

entry

entry可以是个字符串或数组或者是对象。

当entry是个字符串的时候,用来定义入口文件:

entry: './js/main.js'

当entry是个数组的时候,里面同样包含入口js文件,另外一个参数可以是用来配置webpack提供的一个静态资源服务器,webpack-dev-server。webpack-dev-server会监控项目中每一个文件的变化,实时的进行构建,并且自动刷新页面:

entry: [
      'webpack/hot/only-dev-server',
      './js/app.js'
]

当entry是个对象的时候,我们可以将不同的文件构建成不同的文件,按需使用,比如在我的hello页面中只要\<script src='build/Profile.js'></script>引入hello.js即可:

entry: {
      hello: './js/hello.js',
      form: './js/form.js'
}  

 

output

output参数是个对象,用于定义构建后的文件的输出。其中包含path和filename:

output: {
      path: './build',
      filename: 'bundle.js'
}    

 

module

关于模块的加载相关,我们就定义在module.loaders中。这里通过正则表达式去匹配不同后缀的文件名,然后给它们定义不同的加载器。

module: {
    //加载器配置
        loaders: [
            { test: /\.css$/, loader: 'style-loader!css-loader'},
            { test: /\.jsx?$/, loader: 'babel',exclude: /node_modules/,query: {presets: ['es2015','react']}},
            { test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192'}
        ]
 }

 

resolve

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

resolve: {
        root: 'E:/react/app', //绝对路径
        extensions: ['', '.js','css'],
        alias: {
            ReactDom : 'react-dom.js'
        }
    }

 

plugin

webpack提供了丰富的组件用来满足不同的需求,当然我们也可以自行实现一个组件来满足自己的需求。

plugins: [
      new webpack.optimize.CommonsChunkPlugin('common.js');    
],

 

externals

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

externals: {
      "jquery": "jQuery"
}

 

这样我们就可以放心的在项目中使用这些API了:var jQuery = require("jquery");

 

webpack与gulp并不矛盾,甚至一起使用会得到最大化的利益。使用webpack进行assets编译,使用gulp进行打包似乎就是为了让它们各司其职,用其所长。

 

react-hot-loader加载器:   

配置一个react-hot加载器,通过它,可以实现对react组件的热替换。

在entry参数中配置了`webpack/hot/only-dev-server`,所以我们只要在启动webpack开发服务器时开启--hot参数,就可以使用react-hot-loader了。

"scripts": {
      "start": "webpack-dev-server --hot --progress --colors",
      "build": "webpack --progress --colors"
}

 

webpack-dev-server:web服务器

一个基于Node.js Express框架的开发服务器,它是一个静态资源Web服务器,对于简单静态页面或者仅依赖于独立服务的前端页面,都可以直接使用这个开发服务器进行开发。在开发过程中,开发服务器会监听每一个文件的变化,进行实时打包,并且可以推送通知前端页面代码发生了变化,从而可以实现页面的自动刷新。

 

react-hot-loader +  webpack-dev-server  可以实现类似gulp-connect的功能: 构建服务器,代码修改实时刷新

 

1.下载安装两个插件

npm install -g webpack-dev-server

npm install —save-dev react-hot-loader

 

2.之后,Webpack开发服务器需要开启HMR参数hot,为了方便,我们创建一个名为server.js的文件用以启动Webpack开发服务器:

var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var config = require('../webpack.config');
new WebpackDevServer(webpack(config), {
  publicPath: config.output.publicPath,
  hot: true,
  noInfo: false,
  historyApiFallback: true
}).listen(3000, '127.0.0.1', function (err, result) {
  if (err) {
    console.log(err);
  }
  console.log('Listening at localhost:3000');
});

 

3.为了热加载React组件,我们需要在前端页面中加入相应的代码,用以接收Webpack推送过来的代码模块,进而可以通知所有相关React组件进行重新Render。加入这个代码很简单:

entry: [
  'webpack-dev-server/client?http://127.0.0.1:3000', 
  'webpack/hot/only-dev-server',
  './scripts/entry' 
]

PS: output里面还需要配置一个publicPath,serverJS里面有用到

需要注意的是,这里的client?127.0.0.1:3000需要和在server.js中启动Webpack开发服务器的地址匹配。

 

4.配置一下plugins,加上热替换的插件和防止报错的插件:

plugins: [
  new webpack.HotModuleReplacementPlugin(),
  new webpack.NoErrorsPlugin()
]

 

 

5.下一步,我们需要让Webpack用react-hot-loader去加载React组件,如上一节所介绍,这通过加载器配置完成:

loaders: [{
    test: /\.js$/,
    exclude: /node_modules/,
   include : './app'       loader:
'react-hot!jsx-loader?harmony' }, … ]

PS: loaders里面的include是必须的。。。。不然会报错 

 

做完这些配置之后,使用Node.js运行server.js:

node server.js

 

这样,React的热加载开发环境即配置完成,任何修改只要以保存,就会在页面上立刻体现出来。无论是对样式修改,还是对界面渲染的修改,甚至事件绑定处理函数的修改,都可以立刻生效,不得不说是提高开发效率的神器。

 

 

babel-loader加载器:babel用于解析es6 

1.下载babel加载器

npm install --dave-dev babel-loader

 

2.在加载器中使用babel:

{ test: /\.jsx?$/, loader: 'babel-loader'},

运行代码,webpack会报错(解析es6和jsx均不成功),这是为什么呢?

babel-loader解析es6,还需要插件支持,同时解析jsx也需要插件支持:

npm install --dave-dev babel-preset-es2015     
npm install --dave-dev babel-preset-react

配置

{ 
    test: /\.jsx?$/, 
    loader: 'babel',
    exclude: /node_modules/,
    query: {
        presets: [
            'es2015',
            'react'
        ]
    }
},        

这样就可以成功解析es6和jsx了