webpack的一点介绍

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

Webpack 把任何一个文件都看成一个模块,模块间可以互相依赖(require or import),webpack 的功能是把相互依赖的文件打包在一起。webpack 本身只能处理原生的 JavaScript 模块,但是 loader 转换器可以将各种类型的资源转换成 JavaScript 模块。这样,任何资源都可以成为 Webpack 可以处理的模块。同时,webpack还有丰富的插件 plugin,可以完成例如js,css的压缩,公共依赖模块的提取和注入,甚至利用模板对 html 进行动态拼接等功能。

同时,webpack 使用commonjs规范(require),支持es6语法(import)的编译,可以方便的抽离vue组件,这成为我们选择它的重要理由。

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

 

对webpack工作方式直观的理解(官网小示例)

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

import: es6 引入依赖的方式,还可以用commonjs 规范的require

var bar  = require('./bar')

module.exports: commonjs规范中对外暴露本模块接口的方式。每个模块内部,都有一个module对象,代表当前模块,module对象包含module.id,module.filename,module.exports等信息

entry: 编译的入口js文件,即需要处理的js文件(所有的其他模块包括image,css,vue组件,html模板等都是通过js依赖引入进来的)

output: 编译的出口js文件,即经过打包其他资源、合并、压缩等处理之后生成的js文件

本示例中因为 app.js 依赖 bar.js ,所以打包之后的 bundle.js 可以理解为app.js和bar.js合并后的js

命令行工具中运行:wepack 即编译成功

 


 

实际项目中的webpack解析

本项目已支持功能

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

 1 对less编译
 2 对js es6语法支持
 3 编译.vue组件,并自动内联组件样式
 4 图片打包,包括对html内图片处理(利用html-loader和es6字符串模板),对小图片生成base64
 5 利用htmlWebpackPlugin动态拼接html 的公共部分和内容部分,引入相应css/js资源,并构建到指定目录, 对ejs模板支持
 6 对js内依赖的css分离并压缩
 7 对js引用的公共模块抽取分离成单独文件
 8 区分开发环境和生产环境
 9 js 压缩
10 静态文件(css/js/img)hash版本支持
11 清除目标文件目录
12 eslint支持并实现自动修复部分问题
13 vue接口请求axios支持
14 热更新,自动编译并刷新浏览器

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

 

项目目录结构

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

  |__ html
        |__ dist
              |__ income.html
              |__ index.html
        |__ src
              |__ income
                |__ income.ejs
                |__ income.js
              |__ index
                |__ index.ejs
                |__ index.js
              |__ layouts
                |__ footer.ejs
                |__ header.ejs
                |__ layout.ejs
                |__ layout.js
                |__ side-menu.e
                |__ top-nav.ejs
  |__ dist
        |__ css
        |__ img
        |__ js
              |__ income.js
              |__ index.js
              |__ manifest.js
              |__ vendors.js
  |__ src
        |__ css
        |__ img
        |__ js
              |__ component
                |__ App.vue
              |__ income.js
              |__ index.js
              |__ lib
                |__ axios.min.js
                |__ layer.js
                |__ vue.js
                |__ vue.min.js
  |__ mock
  |__ node_modules
  |__ webpack-config
        |__ .eslintrc.dev.js
        |__ .eslintrc.js
        |__ postcss.config.js
        |__ resolve.config.js
  |__ package.json
  |__ .babelrc
  |__ .eslintrc.js

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

 

一. entry介绍

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

var entries = getEntry('./src/**/*.js') // 获得入口js文件entries.vendors = ['vue','axios']

module.exports = {     /* 输入文件 */
    entry: entries}

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

通常我们的项目中有大量的js入口文件,基本一个功能页面有一个js,这时我们的 entry 文件为一个对象格式

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

'./src/js/income.js''./src/js/index.js'
  vendors: [ 'vue', 'axios'

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

key 值为对应模块的别名,webpack会依次处理这些模块。

vendors 为公共模块,这里我们把vue, axios设置为公共模块,供下面进行提取公共模块操作。

 

之所以可以直接写vue, axios,是因为我们在 alias 里设置了别名:

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

var path = require('path')

module.exports = {  // 模块别名的配置,为了使用方便,一般来说所有模块都是要配置一下别名的  alias: {    'vue': path.resolve(__dirname, '../src/js/lib/vue.min.js'),    'axios': path.resolve(__dirname, '../src/js/lib/axios.min.js')
  }
}

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

 

这里的 path.resolve 作用是把相对路径转为绝对路径,假设我项目建在d:/demo 目录下,

_dirname: d:\demo

path.resolve(__dirname, '../src/js/lib/vue.min.js'): d:\demo\src\js\lib\vue.min.js

 

getEntry() 为获取文件路径的自定义函数:

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

var glob = require('glob')

 entries =
        (entry.indexOf('layouts') == -1 && entry.indexOf('lib') == -1==

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

通常webpack的entry入口文件,是功能性页面的js,对于js库等文件不需要列入入口文件进行处理。所以这里对lib文件夹进行了排除。layouts文件夹为获取html路径时需要排除的文件路径。

 

二. output介绍

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

module.exports = {
    output: {        /* 输出目录,没有则新建 */
        path: path.resolve(__dirname, './dist'),        /* 静态目录,可以直接从这里取文件 */
        publicPath: 'http://www.xxx.com/dist/',        /* 文件名 */
        filename: 'js/[name].js?v=[chunkhash:8]'
    }
}

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

 publicPath: 如果有这项,则html中的引用的js路径会加上publicPath,即 http://www.xxx.com/dist/js/[name].js?v=[chunkhash:8]

 filename: 这里可以自定义输出后的文件名,加上版本号

  [name] :输入模块的别名

  [chunkhash] : 模块的hash值,":8"代表保留8位hash值

  [hash] : 整个编译环境的hash值

hash和chunkhash具体区别请看这里

 

三. module介绍

loaders: webpack利用各种loader来把不同格式的文件封装成模块加载到js内,比如css-loader, vue-loader

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

-+/\.css$/--         "style-loader"-         "css-loader?modules=true"
+++           loader: "style-loader"
+++           loader: "css-loader"++             modules: ++/\.jsx$/"babel-loader",

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

 

eslint-loader

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

module: {
    rules: [
           {
                test: /\.js$/,
                enforce: 'pre',
                loader: 'eslint-loader',
                include: path.resolve(__dirname, './src/js/**/*.js'),
                exclude: ['./src/js/lib','./src/js/component'],
                options: {
                    fix: true
                }
            }  
    ]          
}

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

目的是 对js进行代码风格和语法的校验

enforce: 注意这是webpack v2的变动,v1是 preLoaders。设置为pre表示对js的校验在编译之前进行,我们只负责自己写的js 语法和规范没有问题即可,编译后的代码什么样都不管。

通常我们只对自己写的js进行校验,类库和包里的js无需校验。include即声明我们对哪些文件进行校验,相反,exclude是排除校验哪些文件。

fix:true 即在编译时自动修复代码风格和语法问题

 

babel-loader

{
    test: /\.js$/,
    loader: 'babel-loader',
    exclude: ['node_modules','./src/js/lib','./src/js/component']
}

es6语法目前很多浏览器不支持,我们需要将其转化为大部分浏览器支持的es5语法,这就需要babel-loader

 

css-loader style-loader post-loader less-loader

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

{   
    test: /\.css$/, 
    use: ['style-loader', 'css-loader', 'postcss-loader']
},
{
    test: /\.less$/,
    use: ExtractTextPlugin.extract(['css-loader','postcss-loader','less-loader'])
}

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

对于有多个loader时,webpack v2也废弃了v1的 " !" 连接,改为数组形式,且不能省略 " -loader " 以免造成名称混乱意思模糊,执行顺序为从右到左

postcss-loader为集合处理css各种问题的平台,其上面有各种插件来处理css,我们这里只用到了autoprefixer插件,后面插件部分会详解

style-loader:可以将css以style内联方式嵌入到html页面

ExtractTextPlugin:提取css, 后面插件部分会进行详解

 

file-loader url-loader 处理图片

{
    test: /\.(png|jpg|gif)$/,
    loader: 'url-loader?limit=5120&name=img/[name].[ext]?v=[hash:8]'}

webpack中处理图片用file-loader,但url-loader有个好处,它可以把小图片转化成base64格式,其他的大图片再用file-loader处理,这里的limit即为临界值,这里定义小于5k图片转成base64格式,大于5k的用file-loader处理。

name: 可以重新定义处理后的图片并加上版本值。

 

 四. 插件plugin 

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

module: {},
plugins: [        new ExtractTextPlugin('css/[name].css?v=[contenthash:6]'),        new webpack.LoaderOptionsPlugin({
            options: {
                eslint: require( './webpack-config/.eslintrc.js'),
                postcss: require( './webpack-config/postcss.config.js')
            },
        })
    ]

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

 

插件可以补充loader的功能,对其进行丰富完善,webpack声明插件的方式可以像上面的写法也可以如下方式:

module.exports.plugins.push(new htmlWebpackPlugin())

 亦或

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

module.exports.plugins = module.exports.plugins.concat([        //压缩css代码
        new OptimizeCssAssetsPlugin({
            assetNameRegExp: /\.css/g,
            cssProcessor: require('cssnano'),
            cssProcessorOptions: { discardComments: {removeAll: true } },
            canPrint: true
        }),        //压缩JS代码
        new webpack.optimize.UglifyJsPlugin({
            output: {
                comments: false, // 去掉注释内容            }
        })
    ])

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

通常后两种写法用于动态的使用插件。

 

extract-text-webpack-plugin 插件

默认情况下,js依赖引入css,编译后,css被加在js中,如果我们想把css提取出一个单独的文件,可以使用这个插件,并可以对提取出的css进行自定义命名和加版本hash值

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

income.js中依赖income.less

如果不使用extractTextPlugin,编译后的目录结构为

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

查看income.js,发现css被引入在js之中,模块id为16

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

再看下webpack sourcemap下的income.less,css-loader已经将此文件编译成对外暴露的模块形式,模块id为16

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

使用extractTextPlugin插件后

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

income.js依赖的income.less被单独提出,income.js中引入的模块16发现提示 removed by extract-text-webpack-plugin,再看下此时的income.less

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

提示 removed by extract-text-webpack-plugin , 说明此插件已经顺利的将js中的css提取成单文件形式

同时发现html中已插入income.css

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

这个是style-loader起的作用

 

LoaderOptionsPlugin插件

加载插件的配置项,比如eslint的语法配置,postcss的插件配置

 

optimize-css-assets-webpack-plugin 插件

压缩css文件,对从js中提取出的css文件亦有效

注意:此插件是在css被提取出来加了hash值后进行处理,如果css文件提出来后被命名为  css/[name].css?v=[contenthash:8] 形式,插件的使用如下

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

new OptimizeCssAssetsPlugin({
            assetNameRegExp: /\.css/g,  //注意不要写成 /\.css$/g, 否则匹配不到css文件会导致压缩不成功
            cssProcessor: require('cssnano'),
            cssProcessorOptions: { discardComments: {removeAll: true } },
            canPrint: true
        })

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

 

html-webpack-plugin 插件

 用于根据模板组合html各个部分,并插入对应引用的js,对前后端分离贡献颇多,功能强大会有专门的篇章来介绍

 

 browser-sync-webpack-plugin 插件

热更新,自动刷新浏览器

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

var BrowserSyncPlugin = require('browser-sync-webpack-plugin')

module.exports = {
    plugins: [        new BrowserSyncPlugin({
            host: 'localhost',
            port: 3000,
            server: { baseDir: ['./'] }
        })
    ]
}

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

 

baseDir: localhost:3000 指定的目录

结合webpack的watch,可以做到实时编译并刷新浏览器

只需要  webpack --watch  即可

 

CommonsChunkPlugin 插件

提取js的公共模块,此插件为webpack自带的插件

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

// 提取公共模块new webpack.optimize.CommonsChunkPlugin({
    names:  ['vendors', 'manifest'], // 公共模块的名称
    //filename: 'js/[name]-[chunkhash:6].js', // 公共模块的名称
    chunks: 'vendors',  // chunks是需要提取的模块
    minChunks: Infinity  //公共模块最小被引用的次数})

平面设计培训,网页设计培训,美工培训,游戏开发,动画培训

通常我们的js可能会引入一些公共js文件,包括一些类库,如果都打包在一个js中,这个js会变得非常

转载请注明出处 https://i.cnblogs.com/EditPosts.aspx?postid=6635504

 

http://www.cnblogs.com/saysmy/p/6635504.html