手记

gulp + webpack 构建多页面入口web应用

目录
---1. webpack 安装
---2. webpack 命令行常用功能
---3. Gulp+webpack 实践项目目录结构
---4. webpack 的用法
---5. webpack 如何加载第三方库?
---6. 如何启动webpack 服务器?
---7. 对Gulp 和webpack 结合使用的意义

1.webpack 安装(基于Nodejs)
我们可以直接使用npm进行全局安装

npm install webpck -g

在常规项目中把webpack依赖加入到package.json

npm install webpack --save-dev

2.webpack 命令行常用功能
(1) 单独启动webpack

webpack

(2) 如果你想当改变一个文件而让webpack实时编译(单独使用webpack)

webpack --watch

3.项目目录结构说明

我们的项目是一个多页面项目,即每个页面为一个html,访问不同的页面需要跳转链接。项目目录结构大概是这样的,src 目录下 wxPages 存放html文件,scss为样式文件,javascripts下有不同的文件夹,里面的子文件夹为一些核心文件和一些库文件,ui组件.

4.webpack的用法
这里是实战项目中使用的webpack.config.js 配置文件:
配置项参考文档

打包思路
该配置方案的思路是每个页面一个入口文件,文件中可以通过require引入其他模块,而这些模块webpack会自动跟入口文件合并为一个文件

var webpack= require('webpack');
var path = require('path');
var defaultSettings = require('./defaults');
var ExtractTextPlugin = require('extract-text-webpack-plugin');//理解该插件的作用
var HtmlWebpackPlugin = require('html-webpack-plugin');//理解该插件的作用
var filePath = defaultSettings.filePath;//defaults 中路径配置的json key-value值
var precss = require("precss");//css的预处理功能
var autoprefixer = require('autoprefixer'); //自动补充css前缀功能

var webpackConfig={
    entry: {},//entry,获取项目入口js文件, 入口函数表示出那些事需要单独打包成一个js包的,由于是多页面项目,多个入口,entry 参数由下面函数injectEntry() 返回入口文件数据.
    output:{
        path:filePath.build,//文件输出目录,用于配置文件发布路径,如CDN或本地服务器
        filename:'[name].js',// //根据入口文件输出的对应多个文件名
        publicPath: filePath.publicPath
    },
    cache:true,
    devtool: 'inline-source-map',//生成sourcemap,便于开发调试
    resolve: {
       //模块决议配置
        extensions: ['', '.js', '.jsx'],
        //配置别名,在项目中可缩减引用路径
        alias: {
          'components': path.join(__dirname, '../src/javascript/components'),
          'lib': path.join(__dirname, '../src/javascript/lib'),
          'extend': path.join(__dirname, '../src/javascript/extend'),
          'page': path.join(__dirname, '../src/javascript/page'),
          'scss': path.join(__dirname, '../src/scss'),
          //'pages': path.join(__dirname, '../src/wxPages'),
          'images': path.join(__dirname, '../statics/images'),
          'mock': path.join(__dirname, '../src/javascript/mock'),
          'fonts': path.join(__dirname, '../res/fonts'),
          'jquery': path.join(__dirname, '../src/javascript/lib/jquery-3.1.1.js')
        }
    },
    module:{
                //module的作用是添加loaders, 那loaders有什么作用呢?
        //各种加载器,即让各种文件格式可用require引用
        //如果我们想要在js文件中通过require引入模块,比如css或image,那么就需要在这里配置加载器,这一点对于React来说相当方便,因为可以在组件中使用模块化CSS。而一般的项目中可以不用到这个加载器。
//exclude参数说明 ,排除 node_modules 下不需要转换的文件,可以加快编译
        loaders: [
              {
                test: /.jsx?$/,
                loaders: ['react-hot', 'babel-loader?presets[]=es2015&presets[]=react&presets[]=stage-0&presets[]=stage-1', 'webpack-module-hot-accept'],
                exclude: /node_modules/
              },
              {
                test: /\.scss/,
                loader: 'style!css!postcss!sass?outputStyle=compressed',
              },
              {
                test: /\.css$/,
                loader: 'style!css!postcss',
              },
              {
                test: /\.(png|jpg|gif|woff|woff2|eot|ttf|svg)$/,
                loader: 'url-loader?limit=1&name=res/[name].[hash:8].[ext]'
              },
              {
                test: /\.json$/,
                loader: 'json-loader'
              },
              {
                test: /\.ftl$/,
                loader: 'raw-loader'
              }
        ]
    },/*
    postcss:function () {
        return [precss,autoprefixer]
    },*/
    plugins:[
        ////提供全局的变量,在模块中使用无需用require引入
        /*new webpack.ProvidePlugin({
          $: "jquery",
          jQuery: "jquery",
          "window.jQuery": "jquery",
          "Modernizr": "Modernizr"
        })*/
        new webpack.HotModuleReplacementPlugin(),
        new ExtractTextPlugin('[name].css'),
        new webpack.NoErrorsPlugin()
    ]
};

//入口注入
//那如果我们想要将打包好的js存放在指定的位置又要如何进行操作呢
function injectEntry() {
  defaultSettings.pagesToPath().forEach(function (item) {
    webpackConfig.entry[item.name] = [
      'webpack-dev-server/client?http://localhost:' + defaultSettings.port,
      'webpack/hot/only-dev-server',
      item.entry
    ];

  });

  //console.log('webpackConfig.entry', webpackConfig.entry);
  //['webpack-dev-server/client?http://localhost:8090','webpack/hot/only-dev-server','Page/FillInfo/index.jsx']
}

function injectHtmlWebpack() {
  defaultSettings.pagesToPath().forEach(function (item) {
    webpackConfig.plugins.push(
      new HtmlWebpackPlugin({
        filename: item.ftl,//'wxPages/FillInfo/index.html'  输出的html文件名,默认是idnex.Html ,也可以直接配置带有子目录
        template: item.templates,// 模板路径地址: "../src/wxPages/FillInfo/index.html " 模板文件路径,支持加载器
        chunks: [item.name],//允许只添加某些块FillInfo/index
        inject: true //注入所有的资源到特定的templage 中
      })
    );
  });
}
//html-webpack-plugin 可以帮助生成 HTML 文件

(function () {
  injectEntry();
  injectHtmlWebpack();
})();

module.exports = webpackConfig;

webpack.config.js的写法和在Node里的写法相同,我们主要看的就是文件中的module.exports里面的内容

我们还用到一个字段是 devtool , 用于配置开发工具。‘source-map’就是在生成的代码中加入sourceMap的支持。能够直接定位到出错代码的具体位置,对sourcemap的使用和原理还不了解的可以看下 【这里】
devtool 配置参数

5.webpack 如何加载第三方库?
在pc开发中我们通常会用到jQuery库。如何很好地处理这类文件呢?这里有两种办法。
方法一:是在html中用script标签引入js文件,如

 <script type="text/javascript" src="./lib/jquery-3.1.1.js"></script>

然后再配置文件中添加externals

externals: { jquery: "jQuery" }

该字段的作用是将加jQuery全局变量变为模块可引入。然后在各个模块中,就可以如下使用:

var $ = require("jquery");

例:在一个页面的入口js 文件中可引入使用

我个人觉得既然已经将加jQuery通过script引入了,那么就直接使用$标签就行了。不必再将其转化为模块。
方法二:是将jQuery代码保存到本地,在配置文件中添加:

即为jquery添加了别名,然后在模块中也是这样使用:

var $ = require("jquery")

还可以配合使用ProvidePlugin,其作用是提供全局变量给每个模块,这样就不需要在模块中通过require引入。
使用前:

var $ = require("jquery");
console.log($("div").length);

使用后:

new webpack.ProvidePlugin({
      $: "jquery",
      jQuery: "jquery",
      "window.jQuery": "jquery"
 });

// If you use "_", underscore is automatically required
console.log($("div").length);

建议:如果文件来自CDN,那么使用方法一,如果文件在本地,则用方法二。

webpack 插件:https://github.com/webpack/docs/wiki/list-of-plugins

6.如何更方便得启动webpack 服务器?
由于webpack服务器配置比较繁琐,所以我们的项目还是采用gulp来启动本地服务器。

我们只利用webpack进行了js方面的打包,其他功能用gulp就足够了

  1. 对Gulp 和webpack 结合使用的意义?
    其实webpack结合gulp的原理就是将webpack的出口文件作为gulp的入口文件。参考文献

单独使用webpack 打包,可以通过命令webpack --watch 打包生成物理文件.
当gulp 和webpack 结合打包生成物理文件,需要使用插件gulp-webpack,然后根据webpack.config.js (或者webpack.dist.config.js)配置生成打包后的目录文件.

  1. 彻底解决Webpack打包性能问题
    参考文献: https://zhuanlan.zhihu.com/p/21748318
7人推荐
随时随地看视频
慕课网APP

热门评论

testtesttesttesttesttesttest

查看全部评论