Webpack使用指南,试试多少个办法

By admin in 4858美高梅 on 2019年5月7日

Webpack是个很盛行的包装工具,但其包装速度却直接被嘲弄着

若是不用上一些包裹的优化建议,单单打包两四个文本就会花上有些秒,放上几13个输入文件倚重几百上千个包的话,几分钟17分钟妥妥的

4858美高梅 ,本文整理了布满的壹部分措施,部分应用之后就看出了极大改良,部分没什么分明的转换,也说不定是项目规模还不够大,先记下一下方法能够

不久前在做的连串因为相对一点都不小(打包有十0多少个chunk),在build创设的时候速度平昔上不去,甚是烦恼。由于用的是vue-cli的webpack2模板,1开端并从未想着要对其展开优化,一向以为是webpack本人慢+硬件慢(在支付机上开荒,内部存款和储蓄器和CPU都不是很强力)的原原本本的经过。后来慢到骨子里受不了了,转移到地面(i七+1陆G)开荒的时候,发掘生产创设居然须要90s,实在太长了。所以初始最先Webpack二创设优化。

Webpack 是当下最火爆的前端财富模块化管理和包装工具。

大概太慢了,快速使用Webpack四

  • 优化webpack创设速度,总的来讲有多少个思路:

什么是webpack

Webpack
是立刻最热门的前端财富模块化管理和打包工具。它能够将过多麻痹的模块依照注重和规则打包成符合生产条件安排的前端财富。还是可以将按需加载的模块举办代码分隔,等到实际要求的时候再异步加载。通过
loader 的改动,任何方式的能源都足以当作模块,举个例子 CommonJs 模块、 AMD模块、 ES6 模块、CSS、图片、 JSON、Coffeescript、 LESS 等。

4858美高梅 1

1、使用监听情势或热更新热替换

webpack协助监听形式,此时内需再行编写翻译时就可以张开增量构建,增量营造是全速的,基本不到一秒或几秒之内就能够重新编译好

只顾区分一下支出遭受和线上蒙受,开垦蒙受启用热更新替换

// 开发环境设置本地服务器,实现热更新
    devServer: {
        contentBase: path.resolve(__dirname, 'static'),
        // 提供给外部访问
        host: '0.0.0.0',
        port: 8388,
        // 允许开发服务器访问本地服务器的包JSON文件,防止跨域
        headers: {
            'Access-Control-Allow-Origin': '*'
        },
        // 设置热替换
        hot: true,
        // 设置页面引入
        inline: true
    },

    // 文件输出配置
    output: {
        // 设置路径,防止访问本地服务器相关资源时,被开发服务器认为是相对其的路径
        publicPath: 'http://localhost:8188/dist/js/',
    },


// 插件配置
    plugins: [
        // 热更新替换
        new webpack.HotModuleReplacementPlugin()
    ]

线上蒙受的编写翻译,加个 –watch
参数就可以了

 

  1. 优化自身项目布局,模块的引入、拆分、共用
  2. 优化结构路线、让webpack接管的文书能够急速稳定
  3. 优化uglify编写翻译速度
  4. 优化webpack本人编写翻译速度
    稍许是在付出的时候代码层面上的,有个别则是急需在webpack配置范围上的。对于开荒规模上的话,按需引进是很主要的少数。平常为了方便大家得以一贯引入贰个echarts,可是实际上并没有须求echarts的具有机能。而按需引进则能最大程度上让

Webpack 的特点

Webpack 和其余模块化学工业具有啥样界别吧?

  • 代码拆分
    Webpack
    有二种集人体模型块依赖的法子,同步和异步。异步重视作为分割点,产生二个新的块。在优化了依赖树后,每二个异步区块都当做1个文书棉被服装进。
  • Loader
    Webpack 本人只好处理原生的 JavaScript 模块,不过 loader
    转变器能够将各体系型的财富调换到 JavaScript
    模块。那样,任何财富都得以产生 Webpack 能够拍卖的模块。
  • 智能分析
    Webpack
    有三个智能解析器,差不多能够拍卖任何第一方库,无论它们的模块格局是
    CommonJS、 AMD 依然平常的 JS
    文件。乃至在加载信赖的时候,允许采纳动态表明式
    require(“./templates/” + name + “.jade”)。
  • 插件系统
    Webpack
    还有3个作用丰裕的插件系统。大诸多内容成效都是根据这么些插件系统运维的,还足以付出和平运动用开源的
    Webpack 插件,来满意五花八门的要求。
  • 迅猛运营
    Webpack 使用异步 I/O 和多种缓存升高运营效能,那使得 Webpack
    能够以令人狐疑的快慢神速增量编写翻译。

贰、开垦条件不做无意义的操作

过多配备,在开垦阶段是无需去做的,大家得以分别出开荒和线上的两套配置,那样在急需上线的时候再全量编译就能够

诸如 代码压缩、目录内容清理、总结文件hash、提取CSS文件等

 

  • 总得来讲效用最大的有那多少个:

始于选拔

3、选取3个合适的devtool属性值

布局devtool能够协助使用sourceMap,但多少是耗费时间严重的,这一个得多试试

 

  1. 开启webpack的cache
  2. 开启babel-loader的cache
  3. 钦定modules以及配置项目相关的alias
  4. 配置loader的include和exclude
  5. 用CommonsChunkPlugin提取公用模块
  6. 使用DllPlugin和DllReferencePlugin预编译
  7. 换用happypack多进度营造
  8. css-loader换成0.14.5版本。
  9. 换用webpack-uglify-parallel并行压缩代码

安装

第2要安装 Node.js, Node.js 自带了软件包管理器
npm,Webpack可以由此npm去安装。

用 npm 安装 Webpack:

$ npm install webpack -g

那时 Webpack 已经设置到了大局情形下,能够通过命令行 webpack -h 试试。

普普通通我们会将 Webpack 安装到花色的信赖中,那样就可以使用项目本地版本的
Webpack。

# 进入项目目录
# 确定已经有 package.json,没有就通过 npm init 创建
# 安装 webpack 依赖
$ npm install webpack --save-dev

查看webpack

# 查看 webpack 版本信息
$ npm info webpack

设置钦点版本的 webpack

$ npm install webpack@1.12.x --save-dev

即使急需使用 Webpack 开采工具,要独自安装:

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

肆、代码压缩用ParallelUglifyPlugin代替自带的 UglifyJsPlugin插件

自带的JS压缩插件是单线程推行的,而webpack-parallel-uglify-plugin能够相互的实践,在自个儿的小demo中采用后,速度一贯从贰五s变为了1四s

      new webpack.optimize.UglifyJsPlugin({
            sourceMap: true,
            compress: {
                warnings: false
            }
        }),



ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin')

new ParallelUglifyPlugin({
           cacheDir: '.cache/',
           uglifyJS:{
             output: {
               comments: false
             },
             compress: {
               warnings: false
             }
           }
         }),

 

以下的陈设都以依据vue-cli的webpack模板举行的优化。

使用

率先创设三个静态页面 index.html 和贰个 JS 入口文件 entry.js:

<!-- index.html -->
<html>
<head>
  <meta charset="utf-8">
</head>
<body>
  <script src="bundle.js"></script>
</body>
</html>

// entry.js
document.write('It works.')

下一场编写翻译 entry.js 并封装到 bundle.js:

$ webpack entry.js bundle.js

卷入进度会来得日志:

Hash: e964f90ec65eb2c29bb9
Version: webpack 1.12.2
Time: 54ms
    Asset     Size  Chunks             Chunk Names
bundle.js  1.42 kB       0  [emitted]  main
   [0] ./entry.js 27 bytes {0} [built]

用浏览器展开 index.html 将会看到 It works. 。 接下来增添三个模块
module.js 并修改入口 entry.js:

// module.js
module.exports = 'It works from module.js.'

// entry.js
document.write('It works.')
document.write(require('./module.js')) // 添加模块

重新包装 webpack entry.js bundle.js 后刷新页面看到变化

It works.It works from module.js.
Hash: 279c7601d5d08396e751
Version: webpack 1.12.2
Time: 63ms
    Asset     Size  Chunks             Chunk Names
bundle.js  1.57 kB       0  [emitted]  main
   [0] ./entry.js 66 bytes {0} [built]
   [1] ./module.js 43 bytes {0} [built]

Webpack
会分析入口文件,解析包涵依赖关系的逐条文件。那么些文件(模块)都打包到
bundle.js 。Webpack 会给各种模块分配2个唯1的 id 并经过那几个 id
索引和做客模块。在页面运维时,会先实行 entry.js
中的代码,其余模块会在运营 require 的时候再实践。

Webpack使用指南,试试多少个办法。5、css-loader使用0.1五.0以下的本子

据书上说那个本子以上的快慢会慢多数,可是在自个儿的小demo中还没看出明明扭转

 

  • 开启webpack的cache

Loader

Webpack 本身只可以管理 JavaScript
模块,若是要拍卖任何项指标公文,就需求利用 loader 进行转移。

Loader
能够领略为是模块和能源的转变器,它自个儿是三个函数,接受源文件作为参数,重临调换的结果。那样,大家就足以由此require 来加载任何类型的模块或文件,比方 CoffeeScript、 JSX、 LESS
或图表。

先来看看 loader 有怎么样特色?

  • Loader 能够因而管道形式链式调用,每种 loader
    能够把财富转变到任本性式并传递给下二个 loader ,但是最后二个 loader
    必须回到 JavaScript。
  • Loader 能够同步或异步推行。
  • Loader 运维在 node.js 蒙受中,所以能够做此外恐怕的作业。
  • Loader 还行参数,以此来传递配置项给 loader。
  • Loader 能够经过文件扩张名(或正则表达式)绑定给分歧类别的文本。
  • Loader 能够通过 npm 发表和装置。
  • 除外通过 package.json 的 main 钦定,平常的模块也足以导出一个 loader
    来使用。
  • Loader 可以访问布署。
  • 插件能够让 loader 具有越多特点。
  • Loader 能够分发出附加的自由文件。

loader 一般以 xxx-loader 的章程命名,xxx 代表了那么些 loader
要做的转变职能,比如 json-loader

Loader 能够在 require() 引用模块的时候增进,也足以在 webpack
全局配置中张开绑定,还是可以够通过命令行的办法使用。

接上一节的例子,大家要在页面中引进一个 CSS 文件 style.css,首页将
style.css 也视作是三个模块,然后用 css-loader 来读取它,再用
style-loader 把它插入到页面中。

/* style.css */
body { background: yellow; }

修改 entry.js:

require("!style-loader!css-loader!./style.css") // 载入 style.css
document.write('It works.')
document.write(require('./module.js'))

安装 loader:

npm install css-loader style-loader

双重编写翻译打包,刷新页面,就足以见见鲜绿的页面背景了。

假如每一回 require CSS 文件的时候都要写 loader
前缀,是1件很麻烦的事体。大家得以依附模块类型(扩充名)来机关绑定须求的
loader。

将 entry.js
中的 require("!style-loader!css-loader!./style.css") 修改为 require("./style.css") ,然后实行:

$ webpack entry.js bundle.js --module-bind 'css=style!css'

# 有些环境下可能需要使用双引号
$ webpack entry.js bundle.js --module-bind "css=style!css"

综上可得,那三种采用 loader 的点子,效果是一样的。

六、使用fast-sass-loader代替sass-loader

fast-sass-loader可以相互地管理sass,在付给创设从前会先集体好代码,速度也会快一些

 

打开webpack.base.conf.js,在module.exports里加上cache: true:

铺排文件

Webpack
在实施的时候,除了在指令行传入参数,还足以由此点名的布置文件来实施。暗中同意情状下,会找出当前目录的
webpack.config.js 文件,那些文件是2个 node.js 模块,再次回到3个 json
格式的安顿消息目的,恐怕经过 –config 选项来钦点布置文件。

7、babel-loader开启缓存

babel-loader在试行的时候,可能会爆发部分运营期间重复的国有文件,产生代码体量大冗余,同时也会减慢编译成效

能够增多cacheDirectory参数或选择 transform-runtime 插件试试

// webpack.config.js
use: [{
                loader: 'babel-loader',
                options: {
                    cacheDirectory: true
                }]


// .bablerc
{
    "presets": [
        "env",
        "react"
    ],
    "plugins": ["transform-runtime"]
}

 

module.exports = {
  cache: true,
  // ... 其他配置
}

示例

始建一个布署文件 webpack.config.js:

var webpack = require('webpack')

module.exports = {
  entry: './entry.js',
  output: {
    path: __dirname,
    filename: 'bundle.js'
  },
  module: {
    loaders: [
     {test: /\.css$/,loader: 'style-loader!css-loader'}]
  }
}

捌、无需打包编写翻译的插件库换来全局<script>标签引进的主意

譬如说jQuery插件,react, react-dom等,代码量是大多的,打包起来只怕会很耗费时间

能够直接用竹签引进,然后在webpack布署里选用 expose-loader  或 externals 或 ProvidePlugin 
提需求模块内部使用相应的变量

// @1
use: [{
                loader: 'expose-loader',
                options: '$'
            }, {
                loader: 'expose-loader',
                options: 'jQuery'
            }]


// @2
externals: {
        jquery: 'jQuery'
    },


// @3
        new webpack.ProvidePlugin({
            $: 'jquery',
            jQuery: 'jquery',
            'window.jQuery': 'jquery'
        }),

 

  • 开启babel-loader的cache
    开启了cache的babel-loader,在下次编写翻译的时候,遭受不改变的局地可以一向拿取cache里的始末,能够比较明显地提升营造速度。在loader选项里只需求对babel-loader开启cacheDirectory=true就能够。
    配备cacheDirectory后,babel-loader能够缓存管理过的模块,对于尚未改动过的文本不会再重新编写翻译。

    // ... 其他配置
    module: {
      rules: [
    {
      test: /\.js$/,
      loader: 'babel-loader?cacheDirectory=true'
    },
    // ... 其他loader
      ]
    }
    
  • 安顿modules以及配置项目有关的alias

webpack.config.js参数详解

webpack.config.js文件一般位于项目的根目录中,它自个儿也是叁个专门的学问的Commonjs标准的模块。在导出的配备对象中有多少个基本点的参数:

九、使用 DllPlugin 和 DllReferencePlugin 

那种措施实际上和externals是相仿的,重要用于某些模块未有能够在<script>标签中引进的能源(纯npm包)

Dll是动态链接库的乐趣,实际上便是将这么些npm打包生成三个JSON文件,这些文件里带有了npm包的门路对应新闻

那多个插件要一齐用

首先,新建1个dll.config.js配置文件,先用webpack来打包这么些文件

const webpack = require('webpack');
const path = require('path');

module.exports = {
    output: {
        // 将会生成./ddl/lib.js文件
        path: path.resolve(__dirname, 'ddl'),
        filename: '[name].js',
        library: '[name]',
    },
    entry: {
        "lib": [
            'react',
            'react-dom',
            'jquery'
            // ...其它库
        ],
    },
    plugins: [
        new webpack.DllPlugin({
            // 生成的映射关系文件
            path: 'manifest.json',
            name: '[name]',
            context: __dirname,
        }),
    ],
};

4858美高梅 2

在manifest.json文件中便是呼应的包对应的音讯

下一场在大家的类型布局文件中安插DllReferencePlugin 使用这一个清单文件

    // 插件配置
    plugins: [
        new webpack.DllReferencePlugin({
            context: __dirname,
            manifest: require('./manifest.json')
        }),

 

那一个部分的布署实际上都以对webpack接管的文书路线的有个别配置。通过那么些配置,webpack能够不要本人遍历去寻找模块等,而得以因此大家定义的门道,连忙稳固。特别是node_modules的职分,这一个职分能够通过modules选项配置,节省webpack去搜索的年华。

entry

entry参数定义了打包后的入口文件,有二种写法,各样入口称为3个chunk:

类型 示例 解释
字符串 entry: "./index/index.js" 配置模块会被解析为模块,并在启动时加载。
chunk名为默认为main, 具体打包文件名视output配置而定。 
数组 entry: [‘./src/mod1.js’, […,] ‘./src/index.js’] 所有的模块会在启动时 按照配置顺序 
加载,合并到最后一个模块会被导出。chunk名默认为main
对象 entry:{index: ‘…’, login : […]} 如果传入Object,则会生成多个入口打包文件
keychunk名,value可以是字符串,也可是数组。
{
    entry: {
        page1: "./page1",

        //支持数组形式,将加载数组中的所有模块,但以最后一个模块作为输出
        page2: ["./entry1", "./entry2"]
    },
    output: {
        path: "dist/js/page",
        publicPath: "/output/",
        filename: "[name].bundle.js"
    }
}

该段代码最终会调换四个 page1.bundle.js 和 page二.bundle.js,并存放到
./dist/js/page 文件夹下

十、提取公共代码

行使CommonsChunkPlugin提取公共的模块,能够减掉文件容量,也助长浏览器层的公文缓存,依然相比推荐的

 // 提取公共模块文件
        new webpack.optimize.CommonsChunkPlugin({
            chunks: ['home', 'detail'],
            // 开发环境下需要使用热更新替换,而此时common用chunkhash会出错,可以直接不用hash
            filename: '[name].js' + (isProduction ? '?[chunkhash:8]' : ''),
            name: 'common'
        }),




// 切合公共模块的提取规则,有时后你需要明确指定默认放到公共文件的模块
// 文件入口配置
    entry: {
        home: './src/js/home',
        detail: './src/js/detail',
        // 提取jquery入公共文件
        common: ['jquery', 'react', 'react-dom']
    },

 

而alias是外号。通过编写alias,既能让webpack查找文件定位更加快,在支付的时候,也能少许大多相对路径的../..,在引进模块的时候很有益。

output

output参数是个对象,定义了出口文件的职位及名字:

output: {
        path: "dist/js/page",
        publicPath: "/output/",
        filename: "[name].bundle.js"
    }
  • path: 打包文件存放的相对路线
  • publicPath: 网站运维时的造访路线
  • filename:打包后的公文名

当大家在entry中定义营造多个公文时,filename能够对应的变动为[name].js用于定义分裂文件营造后的名字。

拾一、使用HappyPack来增长速度创设

HappyPack会利用多进度去打包构建,使用格局依旧蛮轻巧的,但并不是协理全数的loader

先是引进,定义一下以此插件所开启的线程,推荐是多个,其实也得以平素动用暗中认可的就行了

HappyPack = require('happypack'),
    os = require('os'),
    happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });

接下来在module的条条框框里改造一下,引进它,在那之中 id是八个标记符

{
            test: /\.jsx?$/,
            // 编译js或jsx文件,使用babel-loader转换es6为es5
            exclude: /node_modules/,
            loader: 'HappyPack/loader?id=js'
            // use: [{
            //     loader: 'babel-loader',
            //     options: {

            //     }
            // }]
        }

然后我们调用插件,设置相配的id,然后相关的布局可以一直把use:的平整部分套在loaders上

new HappyPack({
            id: 'js',
            loaders: [{
                loader: 'babel-loader',
                options: {
                    // cacheDirectory: true
                }
            }]
        }),

要专注的率先点是,它对file-loader和url-loader援助倒霉,所以那八个loader就不必要换到happypack了,别的loader能够接近地换一下

要注意的第2点是,使用ExtractTextWebpackPlugin提取css文件也不是一心就能够改变过来,所以须求小小的退换一下,举个例子

module: {
        rules: [{
            test: /\.css$/,
            // loader: 'HappyPack/loader?id=css'
            // 提取CSS文件
            use: cssExtractor.extract({
                // 如果配置成不提取,则此类文件使用style-loader插入到<head>标签中
                fallback: 'style-loader',
                use: 'HappyPack/loader?id=css'
                // use: [{
                //         loader: 'css-loader',
                //         options: {
                //             // url: false,
                //             minimize: true
                //         }
                //     },
                //     // 'postcss-loader'
                // ]
            })
        }, {
            test: /\.scss$/,
            // loader: 'HappyPack/loader?id=scss'
            // 编译Sass文件 提取CSS文件
            use: sassExtractor.extract({
                // 如果配置成不提取,则此类文件使用style-loader插入到<head>标签中
                fallback: 'style-loader',
                use: 'HappyPack/loader?id=scss'
                // use: [
                //     'css-loader',
                //     // 'postcss-loader',
                //     {
                //         loader: 'sass-loader',
                //         options: {
                //             sourceMap: true,
                //             outputStyle: 'compressed'
                //         }
                //     }
                // ]
            })
        }

因为它是直接函数调用的,大家就停放里层的use规则就行了,然后配置插件就能够

plugins: [
        new HappyPack({
            id: 'css',
            loaders: [{
                loader: 'css-loader',
                options: {
                    // url: false,
                    minimize: true
                }
            }]
        }),
        new HappyPack({
            id: 'scss',
            loaders: [{
                'loader': 'css-loader'
            }, {
                loader: 'fast-sass-loader',
                options: {
                    sourceMap: true,
                    outputStyle: 'compressed'
                }
            }]
        }),

 

同等是开发webpack.base.conf.js,在module.exports的resolve属性里布置modules和alias。个中vue-cli会自动配置部分暗中同意的alias。

module

在webpack中JavaScript,CSS,LESS,TypeScript,JSX,CoffeeScript,图片等静态文件都以模块,分化模块的加载是透过模块加载器(webpack-loader)来统1管理的。loaders之间是能够串联的,多少个加载器的出口可以当作下1个加载器的输入,最终回到到JavaScript上:
loader使用须求先安装再投入到安顿下中。

Loaders须要独自安装还要需求在webpack.config.js下的modules关键字下进展安插,Loaders的布署选项包罗以下几方面:

  • test:2个相称loaders所管理的文书的拓展名的正则表达式(必须)
  • loader:loader的名称(必须)
  • include/exclude:手动加多必须管理的文书(文件夹)或屏蔽不须要管理的文本(文件夹)(可选);
  • query:为loaders提供额外的设置选项(可选)

10二、优化营造时的寻觅路线

在webpack打包时,会有形形色色的门路要去查询检索,咱们能够增加部分公司署,让它寻觅地更加快

比方说,方便改成相对路线的模块路线就改一下,以纯模块名来引进的能够增多有的目录路线

还是能善于用下resolve alias小名 那个字段来布局

再有exclude等的安顿,制止多余查找的文件,比方利用babel别忘了剔除不必要遍历的

{
            test: /\.jsx?$/,
            // 编译js或jsx文件,使用babel-loader转换es6为es5
            exclude: /node_modules/,
             use: [{
                 loader: 'babel-loader',
                 options: {

                 }
             }]
        }

 

 

resolve: {
  //... 其他配置
  modules: [path.resolve(__dirname, '../../node_modules')], // node_modules文件夹所在的位置取决于跟webpack.base.conf.js相对的路径
  alias: {
    //... 其他配置
    api: path.resolve(__dirname, '../../server/api') // api文件所在的位置取决于跟webpack.base.conf.js相对的路径,在项目中会自动转换跟项目文件的相对路径
    //... 其他配置
  }
}
loaders之 预处理
  • css-loader 管理css中路线引用等主题素材
  • style-loader 动态把体制写入css
  • sass-loader scss编译器
  • less-loader less编译器
  • postcss-loader scss再处理


module: {
        //加载器配置
        loaders: [
            //.css 文件使用 style-loader 和 css-loader 来处理
            { test: /\.css$/, loader: 'style-loader!css-loader' },
            //.less 文件使用 less-loader、cssloader来编译
            { test:/\.less$/, loader: 'style!less'}
            //.scss 文件使用 style-loader、css-loader 和 sass-loader 来编译处理
            { test: /\.scss$/, loader: 'style!css!sass?sourceMap'},

        ]
    }

10叁、(导出编写翻译JSON文件)理一下打包创设涉及的模块,分析看有哪些包是没有须要打包的,只打包需求的模块

检查一下代码,看看是否有无需引进的模块出现在代码里

webpack编写翻译时增添参数 –json >
stat.json 后,能够上传到 webpack-analyse
、webpack-visualizer等分析站点上,看看打包的模块音信

 

若是布署了上述的alias,那么大家在类型里,要引用举个例子api.js这一个模块,能够一向那样做了:

loaders之 react处理

babel-loader babel官网

// npm一次性安装多个依赖模块,模块之间用空格隔开
npm install --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-react

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

十4、使用ModuleConcatenationPlugin插件来加快JS实践进程

那是webpack三的新特征(Scope
Hoisting),其实是以史为鉴了Rollup打包工具来的,它将有个别有联系的模块,放到1个闭包函数里面去,通过削减闭包函数数量从而加速JS的施行进度

 new webpack.optimize.ModuleConcatenationPlugin({

        })

 

import * as api from 'api' // 'api'是个alias,webpack会直接去找`server/api`
loaders之 es六转账处理
  • babel-loader 以及 babel-preset-es2015
  • 设置 以上四个插件

     npm install babel-loader --save-dev
     npm install babel-preset-es2015 --save-dev
    
  • 开创bable的布置文件

{
  "presets": ["es2015"]
}

十五、使用noParse

webpack打包的时候,有时无需分析有些模块的借助(这么些模块并不曾注重,或许并根本就一贯不模块化),我们得以直接助长那些参数,直接跳过那种分析

module: {
    noParse: /node_modules\/(jquey\.js)/
  }

 

而不用手动去依照项目文件和api所在门路的周旋地点去书写import的路径了。

loaders之 图片管理
  • url-loader

npm install --save-dev url-loadr

module: {
  loaders: [
    {
      test: /\.(png|jpg|gif)$/,
      loader: 'url-loader?limit=10000&name=build[name].[ext]'
    }
  ]
}

对于地点的配备,就算图片财富小于拾kb就能够转接成 base6肆 格式的
dataUrl,其余的图形会存放在build/images文件夹下。

十六、使用异步的模块加载

以此好不轻便能够减掉模块的体积吧,在自然水准上也是为用户着想的,使用require.ensure来设置哪些模块需求异步加载,webpack会将它包裹到一个单独的chunk中,

在某些时刻(比如用户点击了翻看)才异步地加载那个模块来实施

$('.bg-input').click(() => {
    console.log('clicked, loading async.js')

    require.ensure([], require => {

        require('./components/async2').log();
        require('./components/async1').log();
        console.log('loading async.js done');
    });
});

 

  • 配置loader的include和exclude
loaders之 文件管理
  • file-loader


npm install --save-dev file-loader

module: {
  loaders: [
    {
      test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot)$/,
      loader: 'file'
      },
  ]
}

107、以模块化来引进

稍微模块是能够以模块化来引进的,正是说能够只引进在那之中的一片段,举个例子说lodash

// 原来的引入方式
 import {debounce} from 'lodash';

//按模块化的引入方式
import debounce from 'lodash/debounce';

 

 主假诺收10过来的,试用了多少个章程,第3遍编写翻译的速度能够在此在此以前边半分多钟减小到十秒左右了,当然,开启了热更新替换后大概美不可言

当然还有许多措施没整理出,那些艺术是有利用情形的,并不是每个都亟待用,须要在大团结的项目中品尝,结合配置它的复杂和拉动的作用来衡量。

loader的include和exclude也正是亟需loader接管编写翻译的文件和无需loader接管编写翻译的文书。

示例

module: {
        //加载器配置
        loaders: [
            //.css 文件使用 style-loader 和 css-loader 来处理
            { test: /\.css$/, loader: 'style-loader!css-loader' },


            //.scss 文件使用 style-loader、css-loader 和 sass-loader 来编译处理
            { test: /\.scss$/, loader: 'style!css!sass?sourceMap'},

            //图片文件使用 url-loader 来处理,小于8kb的直接转为base64
            { test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192'}
        ]
    }

这里大家举babel-loader为例。平时情状下,大家不供给loader去编写翻译node_modules下的js文件,而笔者辈只必要编写翻译大家项目目录下的js就行了。那样能够透过安排那八个挑选,能够最小范围的范围babel-loader需求编写翻译的剧情,能够有效提高营造速度。

插件(Plugins)

插件(Plugins)是用来打开Webpack效率的,它们会在全方位营造进程中生效,推行相关的天职。

Webpack有很多停放插件,同时也有很多第二方插件,能够让我们做到越发助长的效应。

1致展开webpack.base.conf.js,在rules的babel-loader那块加上include和exclude。

使用插件的不二等秘书技

要使用有个别插件,我们须求经过npm安装它,然后要做的正是在webpack配置中的plugins关键字部分加多该插件的贰个实例(plugins是一个数组)继续看例子,大家增添了三个完毕版权表明的插件。

module.exports = {
  plugins: [
    new webpack.BannerPlugin("Copyright Nico inc.")
    //在这个数组中new一个就可以了
  ]
}
// ... 其他配置
module: {
  rules: [
    {
      test: /\.js$/,
      loader: ['babel-loader?cacheDirectory=true'],
      include: [resolve('src')], // src是项目开发的目录
      exclude: [path.resolve('../../node_modules')] // 不需要编译node_modules下的js 
    },
    // ... 其他loader
  ]
}

HtmlWebpackPlugin

其一插件的意义是依据二个简易的沙盘,帮你转移最终的HTML5文书,这么些文件中自行引用了您包装后的JS文件。每一遍编译都在文件名中插入3个差异的哈希值。

安装

npm install --save-dev html-webpack-plugin

其一插件自动达成了笔者们从前手动做的一对专门的学问,在正儿8经使用之前须求对平素以来的花色协会做一些退换:

在app目录下,创设2个Html文件模板,这一个模板包涵title等别的你需求的成分,在编写翻译进度中,本插件会依据此模板生成最后的html页面,会活动加多所依赖的
css,
js,favicon等公事,在本例中大家命超模板文件名叫index.tmpl.html,模板源代码如下

index.tmpl.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Webpack</title>
  </head>
  <body>
    <div id='box'>
    </div>
  </body>
</html>

webpack.config.js

var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    plugins: [
    new HtmlWebpackPlugin({
      template: __dirname + "/app/index.tmpl.html"//new 一个这个插件的实例,并传入相关的参数
    })
  ]
}
  • 行使CommonsChunkPlugin提取公用模块

ExtractTextPlugin

分离CSS和JS文件

安装

npm install --save-dev extract-text-webpack-plugin

webpack.config.js

var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
    ...
  plugins: [
    new HtmlWebpackPlugin({
      template: __dirname + "/app/index.tmpl.html"
    }),
    new webpack.optimize.OccurenceOrderPlugin(),
    new webpack.optimize.UglifyJsPlugin(),
    new ExtractTextPlugin("style.css")
  ]
}

我们日常会有那种情景:在a.vue组件里引进了a.js也许诸如c.vue,在b.vue组件里也引进了a.js或然c.vue。那样,打包驾驭后将会把引进的模块重复打包。而CommonsChuncksPlugin正是把那样重复打包的模块给抽出出来单独打包的插件。那些能够掌握下降最终打包的体量,也能升高部分打包速度。

联合公共代码

项目中,对于部分常用的零部件,站点公用模块日常需求与其余逻辑分开,然后合并到同1个文本,以便于长日子的缓存。要落到实处那壹成效,配置参照:

var webpack = require('webpack');
var CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin;
 
···
entry: {
   a: './index/a.js',
   b: './idnex/b.js',
   c: './index/c.js',
   d: './index/d.js'
},
···
plugins: [
   new CommonsChunkPlugin('part.js', ['a', 'b']),
   new CommonsChunkPlugin('common.js', ['part1', 'c'])
]
···

在webpack.base.conf.js里的plugins可以加上那段:

代码压缩

webpack 自带了3个回落插件 UglifyJsPlugin,只须要在安插文件中引进就能够。

{
  plugins: [
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      }
    })
  ]
}

加盟了这些插件之后,编写翻译的速度会明显变慢,所以一般只在生产条件启用。

plugins: [
  new webpack.optimize.CommonsChunkPlugin({
    async: 'shared-module',
    minChunks: (module, count) => (
      count >= 2    // 当一个模块被重复引用2次或以上的时候单独打包起来。 
    )
  }),
  //...
]

别的用法

  • 使用DllPlugin和DllReferencePlugin预编译

缓存

缓存无处不在,使用缓存的最棒法子是确认保障你的文本名和文件内容是相配的(内容改变,名称相应改换)
webpack能够把八个哈希值增加到打包的文书名中,使用形式如下,增添特殊的字符串混合体([name],
[id] and [hash])到输出文件名前

var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
  entry: __dirname + "/app/main.js",
  output: {
    path: __dirname + "/build",
    filename: "[name]-[hash].js"
  },
  module: {},
  plugins: [
    new HtmlWebpackPlugin({
      template: __dirname + "/app/index.tmpl.html"
    }),
    new webpack.optimize.OccurenceOrderPlugin(),
    new webpack.optimize.UglifyJsPlugin(),
    new ExtractTextPlugin("[name]-[hash].css")
  ]
}

其1也是一个大杀器。将一部分大局都要用到的依赖抽离出来,预编译三回,然后引进项目中,作为依据项。而webpack在行业内部编写翻译的时候就能够放过他们了。可以很强烈地进级webpack的营造速度。类似于Windows的dll文件的规划意见。dll能源可以行得通的消除能源循环注重的题材。可以大大减弱项目里再一次正视的标题。

去除多个公文中的频仍依赖

当大家平时使用React、jQuery等外部第二方库的时候,常常在种种业务逻辑JS中都会遭受这几个库。

如大家须求在1一文件中都以有jQuery的$对象,由此大家必要在各样用到jQuery的JS文件的尾部通过require(‘jquery’)来正视jQuery。
那样做老大麻烦且重新,由此webpack提供了大家一种相比连忙的点子,大家能够通过在配备文件中配置利用到的变量名,那么webpack会自动分析,并且在编写翻译时帮大家成功那么些正视的引进。

webpack.config.js中

var webpack = require('webpack');
 
...
plugins: [
   new webpack.ProvidePlugin({
       'Moment': 'moment',
       "$": "jquery",
       "jQuery": "jquery",
       "window.jQuery": "jquery",
       "React": "react"
   })
]
...

在webpack.base.conf.js所在的文件夹里创立三个webpack.dll.conf.js,大家将部分常用的依靠打包成dll。

设置条件命令

要报告webpack大家意在如今是怎么样蒙受,只须求在指令中写入 BUILD_DEV=1webpck 那么webpack通过配备,就能将兼具大家引用到的__DEV__变量设置为true。

小编们能够在package.json中先期定义好命令:

"scripts": {
    "dev": "BUILD_DEV=1 webpack-dev-server --progress --colors",
    "build": "BUILD_PRERELEASE=1 webpack -p"
}

那就是说就足以幸免输入冗长的一声令下了:

开垦时输入:

npm run dev

揭橥时输入:

npm run build

先是配置一下DllPlugin的能源列表。

常用命令


webpack的采纳和browserify有个别看似,上面列举多少个常用命令:

webpack 最基本的启动webpack命令
webpack -w 提供watch方法,实时进行打包更新
webpack -p 对打包后的文件进行压缩
webpack -d 提供SourceMaps,方便调试
webpack --colors 输出结果带彩色,比如:会用红色显示耗时较长的步骤
webpack --profile 输出性能数据,可以看到每一步的耗时
webpack --display-modules 默认情况下 node_modules 下的模块会被隐藏,加上这个参数可以显示这些被隐藏的模块
const path = require('path');
const webpack = require('webpack');
module.exports = {
  entry: {
    vendor: ['vue/dist/vue.esm.js','vue-router','axios','vuex'] // 需要打包起来的依赖
  },
  output: {
    path: path.join(__dirname, '../../public/js'), // 输出的路径
    filename: '[name].dll.js', // 输出的文件,将会根据entry命名为vendor.dll.js
    library: '[name]_library' // 暴露出的全局变量名
  },
  plugins: [
    new webpack.DllPlugin({
      path: path.join(__dirname, '../../public/js/', '[name]-mainfest.json'), // 描述依赖对应关系的json文件
      name: '[name]_library', 
      context: __dirname // 执行的上下文环境,对之后DllReferencePlugin有用
    }),
    new webpack.optimize.UglifyJsPlugin({ // uglifjs压缩
      compress: {
        warnings: false
      }
    })
  ]
}

目录结构

/
 ├── shell/ 脚本
 │
 ├── conf/ 工程配置
 │
 ├── src/ 开发目录
 │      ├── components/ 组件
 │      ├── pages/ 页面
 │      ├──
 ├── dist/ 自动生成
 │
 ├── test/ 测试
 │
 ├── node_modules/ 自动生成,包含.Node 依赖以及开发依赖
 │
 ├── static/ 库文件等,不会被webpack的loader处理,手动管理
 │
 └── etc

完整的目录结构:

projectTemplate/  
    ├── shell/    node脚本    
    │    ├──
    │    ├── dev-server.js  本地开发服务器
    │    ├── build.js  打包脚本
    │    ├── utils.js  工具函数
    │    ├──        
    ├── conf/     工程配置  
    │    ├──
    │    ├── index.js  基础配置文件,在此可简单的修改webpack相关配置
    │    ├── webpack.base.js  webpack的基础配置,主要是loader、resolve的配置
    │    ├── webpack.dev.js  webpack开发配置,主要是eslint、livereload、hot module replacement及相关的插件
    │    ├── webpack.prod.js  webpack生产配置,主要是代码的压缩混淆,图片压缩,加hash
    │    ├── karma.conf.js  测试配置
    │    ├──
    ├── src/   开发目录
    │     ├── components/   组件
    │     ├── pages/        页面(页面下的项目目录需要遵循一定的规范以便创建webpack的入口文件,不过这些规范是可以调整的;以下只是推荐)
    │           ├── index/   首页
    │                ├── images/  图片资源
    │                ├── page.css 样式文件,文件名称可以按照自己意愿命名
    │                ├── page.js  脚本文件及webpack的入口文件,文件名称可以在/conf/index.js配置
    │                ├── template.html 模板文件及要撰写的html文件,文件名称可以在/conf/index.js配置
    │                ├──
    │              
    ├── dist/      自动生成
    │      
    ├── test/      测试(目录可以意愿来创建,但是测试文件名称必须遵循*_test.js的命名规范,可在/conf/karma.conf.js修改配置)
    │  
    ├── node_modules/     自动生成,包含node依赖以及开发依赖
    │  
    ├── static/           库文件等,不会被webpack的loader处理,手动管理
    │     
    └── etc

为了便于之后创设,能够在package.json里拉长那样一句scripts:

使用webpack创设地面服务器

想不想让您的浏览器监测你都代码的修改,并自行刷新修改后的结果,其实Webpack提供三个可选的本地开垦服务器,那几个地面服务器基于node.js构建,能够兑现您想要的那一个效应,然则它是叁个独自的组件,在webpack中张开安插在此以前要求单独安装它当做项目信赖

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

devserver作为webpack配置选项中的壹项,具备以下配置选项

devserver配置选项 功能描述
contentBase 默认webpack-dev-server会为根文件夹提供本地服务器,
如果想为另外一个目录下的文件提供本地服务器,
应该在这里设置其所在目录(本例设置到“public"目录)
port 设置默认监听端口,如果省略,默认为”8080“
inline 设置为true,当源文件改变时会自动刷新页面
colors 设置为true,使终端输出的文件为彩色的
historyApiFallback 在开发单页应用时非常有用,它依赖于HTML5 history API,
如果设置为true,所有的跳转将指向index.html

如下配置:

module.exports = {
    ...
    devServer: {
    contentBase: "./public",//本地服务器所加载的页面所在的目录
    colors: true,//终端中输出结果为彩色
    historyApiFallback: true,//不跳转
    inline: true//实时刷新
  }
}
scripts: {
  //... 其他scripts
  "build:dll": "webpack --config ./webpack/build/webpack.dll.conf.js" // 填写你项目中webpack.dll.conf.js的路径
}

然后实践一下npm run
build:dll,就足以在出口的目录里输出四个vendor.dll.js和vendor-mainfest.json三个文本。

事后展开webpack.base.conf.js。在plugins一项里增进DllReferencePlugin。那些plugin是用于引进上1层里调换的json的。

module.exports = {
  //... 其他配置

  plugins: [
    // ... 其他插件
    new webpack.DllReferencePlugin({
      context: __dirname,
      manifest: require('../../public/js/vendor-mainfest.json') // 指向这个json
    })
  ]
}

谈到底,在品种输出的index.html里,初步引进这么些js:

<script type="text/javascript" src="public/js/vendor.dll.js"></script>

如此那般,webpack将不会再解析dll里的能源了。营造速度将会有质的增高。

  • 换用happypack多进度构建

webpack的构建毕竟还是单进度的。选择happypack可以改为多进程构建。而对于小文件来讲,happypack效果并不明明。而对此babel-loader编写翻译的偌大的js文件群来讲,则是第一次全国代表大会利器。

先是安装:npm install happypack –save-dev或许yarn add happypack

接下来修改webpack.base.conf.js的安插如下:

const os = require('os');
const HappyPack  = require('happypack');
const happThreadPool = HappyPack.ThreadPool({size: os.cpus().length}); // 采用多进程,进程数由CPU核数决定
//...
module.exports = {
  plugins: [
    // ...
    new HappyPack({
      id: 'js',
      cache: true,
      loaders: ['babel-loader?cacheDirectory=true'],
      threadPool: happThreadPool
    })
  ],
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          loaders: {
            js: 'happypack/loader?id=js' // 将loader换成happypack
          }
        }
      },
      {
        test: /\.js$/,
        loader: ['happypack/loader?id=js'], // 将loader换成happypack
        include: [resolve('src')], // src是项目开发的目录
        exclude: [path.resolve('../../node_modules')] // 不需要编译node_modules下的js 
      },
      //...
    ]
  }
}

提速还是比较明确的。

  • css-loader换成0.14.5版本

能够查阅这几个issue,说是该版本之上的本子会拖慢webpack的营造速度。我要好尝试了后头确实能快几分钟。

  • 换用webpack-uglify-parallel并行压缩代码

webpack自带的uglifyjs插件效果确实精确。只可是是因为受限于单线程,所以压缩速度非常矮。换来webpack-uglify-parallel那么些插件之后能够使得减少压缩的光阴。

率先安装:npm install webpack-uglify-parallel –save-dev 恐怕 yarn add
webpack-uglify-parallel

找到webpack.prod.conf.js(由于开垦情势不必要开展uglify压缩),将原来的:

plugins: [
  new webpack.optimize.UglifyJsPlugin({
    compress: {
      warnings: false
    },
    sourceMap: true
  })
  // ... 其他配置
]

替换为:

const UglifyJsparallelPlugin = require('webpack-uglify-parallel');
const os = require('os');
// ... 其他配置
plugins: [
    new UglifyJsparallelPlugin({
        workers: os.cpus().length,
        mangle: true,
        compressor: {
            warnings: false,
            drop_console: true,
            drop_debugger: true
        }
    })        
]
  • 成效综述

经过上述优化,原本90+s的营造时间,优化到30+秒效果仍旧很显明的。原本HMTiggo形式初阶化必要50+秒,也优化到了20+秒的品位。然则,依然有贰个迄今小编本人还不能够化解的难题,那正是HM大切诺基格局,rebuild时间会愈来愈长,直到抢先起头化的20+秒。此时不得不重复开关3回HM牧马人情势。那点本身还无法找到切实可行原因是什么样。可是,至少生产的营造时间获得了6/10的优化,效果还是挺好的。

来源:

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有