1. webpack-打包优化方案
分析打包文件
要优化,先分析。我们先要知道到底是哪里拖慢我们的打包速度呢?
可以利用 webpack-bundle-analyzer 插件来分析我们打包后生成的文件
修改 webpack.prod.conf.js 文件
simple-progress-webpack-plugin 可以显示打包百分比
修改 webpack.prod.conf.js 文件
效果如下:
资源与依赖包的控制
通过上面进度可以看到,打包过程中,卡顿在压缩的地方过长,当项目越来越臃肿的时候,我们要需要对项目静态资源以及依赖包进行整理,
项目里面使用 ElementUI 和 Echarts 都是全部引用挂在 Vue.prototype 上,现都改为按需引用。
预处理各种文件时指定匹配目录后, webpack 解析文件时就不会循环查找其他目录,加快解析速度。
webpack 执行预处理文件时单线程的,我们可以使用 happypack 来多线程处理文件。
修改 webpack.base.js 文件
babel-plugin-dynamic-import-node 插件是使 import() 替换成 require 编译
修虚闹前改 .babelrc 文件
注意 :使用插件 build 后没有 chunk files 文件。
通差清过 DllPlugin 插件分离出第三方包
使用 add-asset-html-webpack-plugin 动态添加 dll.js 到 html 。
需要注意
项目经过以上优化,打包从弯吵 30 分钟,到 2 分钟不到,整体还有优化空间,可以使用其他 cdn 等优化方式。
2. webpack postcss-loader 自动引进postcss.config.js的吗
CommonJs与AMD在一开始,我们先讲一下它和以往我们所用的模块管理工具有什么不一样。在最开始的阶段,Js并没有这些模块机制,各种Js到处飞,得不到有效妥善的管理。后来前端圈开始制定规范,最耳熟能详的是CommonJs和AMD。CommonJs是应用在NodeJs,是一种同步的模块机制。它的写法大致如下:varfirstMole=require("firstMole");//yourcodemole.export=anotherMoleAMD的应用场景则是浏览器,异步加载的模块机制。require.js的写法大致如下:define(['firstMole'],function(mole){//yourcodereturnanotherMole})其实我们单比较写法,就知道CommonJs是更为优秀的。它是一种同步的写法,对Human友好,而且代码也不会繁琐臃肿。但更重要的原因是,随着npm成为主流的JavaScript组件发布平台,越来越多的前端项目也依赖于npm上的项目,或者自身就会发布到npm平台。所以我们对如何可以使用npm包中的模块是我们的一大需求。所以browserify工具就出现了,它支持我们直接使用require()的同步语法去加载npm模块。当然我们这里不得不说的是,ES2015(ES6)里也有了自己的模块机制,也就是说ES6的模块机制是官方规定的,我们通过babel(一种6to5的编译器)可以使用比较多的新特性了,包括我们提到的模块机制,而它的写法大致如下:import{someMole}from"someMole";//yourcodesexportanotherMole;当然上面的写法只是最基本的,还有其他的不同加载模块的写法,可以看一下阮一峰老师的ECMAScript6入门或者babel的相关文档LearnES2015。功能特性browserify的出现非常棒,但webpack更胜一筹!我们来看看webpack支持哪些功能特性:支持CommonJs和AMD模块,意思也就是我们基本可以无痛迁移旧项目。支持模块加载器和插件机制,可对模块灵活定制。特别是我最爱的babel-loader,有效支持ES6。可以通过配置,打包成多个文件。有效利用浏览器的缓存功能提升性能。将样式文件和图片等静态资源也可视为模块进行打包。配合loader加载器,可以支持sass,less等CSS预处理器。内置有sourcemap,即使打包在一起依旧方便调试。看完上面这些,可以想象它就是一个前端工具,可以让我们进行各种模块加载,预处理后,再打包。之前我们对这些的处理是放在grunt或gulp等前端自动化工具中。有了webpack,我们无需借助自动化工具对模块进行各种处理,让我们工具的任务分的更加清晰。
3. webpack如何在页面中异步加载js模块
使用require.ensure作为分割异步模块的点
4. webpack异步加载打包文件名
Webpack异步加载打梁段包文件的文件名由webpack.config.js中歼卖的output.filename配置氏渣逗项决定,默认情况下,文件名包含了[name]、[hash]和[chunkhash]三个变量,可以根据实际情况自定义文件名。
5. require的用法5种
require的用法5种分类:一、commonjs同步。二、commonjs异步加载。三、webpack自带的require.include。四、AMD异步加载。五、ES6 import。
6. webpack到底是通过什么方式在浏览器上加载的呢
Gulp应该和Grunt比较,他们的区别我就不说了,说说用处吧。Gulp / Grunt 是一种工具,能够优化前端工作流程。比如自动刷新页面、combo、压缩css、js、编译less等等。简单来说,就是使用Gulp/Grunt,然后配置你需要的插件,就可以把以前需要手工做的事情让它帮你做了。
说到 browserify / webpack ,那还要说到 seajs / requirejs 。这四个都是JS模块化的方案。其中seajs / require 是一种类型,browserify / webpack 是另一种类型。
seajs / require : 是一种在线"编译" 模块的方案,相当于在页面上加载一个 CMD/AMD 解释器。这样浏览器就认识了 define、exports、mole 这些东西。也就实现了模块化。
browserify / webpack : 是一个预编译模块的方案,相比于上面 ,这个方案更加智能。没用过browserify,这里以webpack为例。首先,它是预编译的,不需要在浏览器中加载解释器。另外,你在本地直接写JS,不管是 AMD / CMD / ES6 风格的模块化,它都能认识,并且编译成浏览器认识的JS。
这样就知道,Gulp是一个工具,而webpack等等是模块化方案。Gulp也可以配置seajs、requirejs甚至webpack的插件。
7. webpack的require和import 有什么区别
1)将filename对应于entry里面生成出来的文件名。
{
entry: {
"index": "pages/index.jsx"
},
output: {
filename: "[name].min.js",
chunkFilename: "[name].min.js"
}
}
生成出来的文件名为index.min.js。
2)按需加载(异步)模块的时候,使用CommonJS的方式异步加载模块,列在entry:
require.ensure(["moles/tips.jsx"], function(require) {
var a = require("moles/tips.jsx");
// ...
}, 'tips');
异步加载的模块是要以文件形式加载,生成的文件名是以chunkname配置的,生成出的文件名就是tips.min.js。
wayou.sayName();
wayou.program();
}, 'Programmer');
let animal = new Animal('mmy');
animal.sayName();
3)(require.ensure() API的第三个参数是给这个模块命名,否则
chunkFilename: "[name].min.js" 中的[name] 是一个自动分配的、可读性很差的id。
4)按照上述修改才可以单纯的指定代码分块的输出目录而又不影响其它资源的打包目录。
8. vue组件异步加载是不是越多越好
vue组件异步加载不是越多越好。异步,是相对于同步而言的。我们在使用Vue时,使用到的改闭组件大多为同步组件。在vue实例第一次执行渲染的过程中,已经生成了组件构造器。而异步组件则是在用到该组件时,异步通过请求去拉取对应组件的js(这里需要和webpack的import相结合)。当核绝裂对应的js加载完成后,获取到异步组件的配置项,从而创建组件构造器。再通过forceRender,强宏稿制依赖它的vm实例重新触发渲染函数。
9. 如何用 webpack fetch 异步引用 json
他像 Browserify, 但是将你的应用打包为多个文件. 如果你的单页面应用有多个页面, 那么用户只从下载对应页面的代码. 当他么访问到另一个页面, 他们不需要重新下载通用的代码.
他在很多地方能替代 Grunt 跟 Gulp 因为他能够编译打包 CSS, 做 CSS 预处理, 编译 JS 方言, 打包图片, 还有其他一些.
它支持 AMD 跟 CommonJS, 以及其他一些模块系统, (Angular, ES6). 如果你不知道用什么, 就用 CommonJS.
2. Webpack 给 Browserify 的同学用
对应地:
browserify main.js > bundle.js
webpack main.js bundle.js
Webpack 比 Browserify 更强大, 你一般会用 webpack.config.js 来组织各个过程:
// webpack.config.js
mole.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
}
};
这仅仅是 JavaScript, 可以随意添加要运行的代码.
3. 怎样启动 webpack
切换到有 webpack.config.js 的目录然后运行:
webpack 来执行一次开发的编译
webpack -p for building once for proction (minification)
webpack -p 来针对发布环境编译(压缩代码)
webpack --watch 来进行开发过程持续的增量编译(飞快地!)
webpack -d 来生成 SourceMaps
4. JavaScript 方言
Webpack 对应 Browsserify transform 和 RequireJS 插件的工具称为 loader. 下边是 Webpack 加载 CoffeeScript 和 Facebook JSX-ES6 的配置(你需要 npm install jsx-loader coffee-loader):
// webpack.config.js
mole.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
mole: {
loaders: [
{ test: /\.coffee$/, loader: 'coffee-loader' },
{ test: /\.js$/, loader: 'jsx-loader?harmony' } // loaders 可以接受 querystring 格式的参数
]
}
};
要开启后缀名的自动补全, 你需要设置 resolve.extensions 参数指明那些文件 Webpack 是要搜索的:
// webpack.config.js
mole.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
mole: {
loaders: [
{ test: /\.coffee$/, loader: 'coffee-loader' },
{ test: /\.js$/, loader: 'jsx-loader?harmony' }
]
},
resolve: {
// 现在可以写 require('file') 代替 require('file.coffee')
extensions: ['', '.js', '.json', '.coffee']
}
};
5. 样式表和图片
首先更新你的代码用 require() 加载静态资源(就像在 Node 里使用 require()):
require('./bootstrap.css');
require('./myapp.less');
var img = document.createElement('img');
img.src = require('./glyph.png');
当你引用 CSS(或者 LESS 吧), Webpack 会将 CSS 内联到 JavaScript 包当中, require() 会在页面当中插入一个 `<style>标签. 当你引入图片, Webpack 在包当中插入对应图片的 URL, 这个 URL 是由require()` 返回的.
你需要配置 Webpack(添加 loader):
// webpack.config.js
mole.exports = {
entry: './main.js',
output: {
path: './build', // 图片和 JS 会到这里来
publicPath: 'http://mycdn.com/', // 这个用来成成比如图片的 URL
filename: 'bundle.js'
},
mole: {
loaders: [
{ test: /\.less$/, loader: 'style-loader!css-loader!less-loader' }, // 用 ! 来连接多个人 loader
{ test: /\.css$/, loader: 'style-loader!css-loader' },
{test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192'} // 内联 base64 URLs, 限定 <=8k 的图片, 其他的用 URL
]
}
};
6. 功能开关
有些代码我们只想在开发环境使用(比如 log), 或者 dogfooging 的服务器里边(比如内部员工正在测试的功能). 在你的代码中, 引用全局变量吧:
if (__DEV__) {
console.warn('Extra logging');
}
// ...
if (__PRERELEASE__) {
showSecretFeature();
}
然后配置 Webpack 当中的对应全局变量:
// webpack.config.js
// definePlugin 接收字符串插入到代码当中, 所以你需要的话可以写上 JS 的字符串
var definePlugin = new webpack.DefinePlugin({
__DEV__: JSON.stringify(JSON.parse(process.env.BUILD_DEV || 'true')),
__PRERELEASE__: JSON.stringify(JSON.parse(process.env.BUILD_PRERELEASE || 'false'))
});
mole.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
plugins: [definePlugin]
};
然后你在控制台里用 BUILD_DEV=1 BUILD_PRERELEASE=1 webpack 编译. 注意一下因为 webpack -p 会执行 uglify dead-code elimination, 任何这种代码都会被剔除, 所以你不用担心秘密功能泄漏.
7. 多个进入点(entrypoints)
比如你用 profile 页面跟 feed 页面. 当用户访问 profile, 你不想让他们下载 feed 页面的代码. 因此你创建多个包: 每个页面一个 "main mole":
// webpack.config.js
mole.exports = {
entry: {
Profile: './profile.js',
Feed: './feed.js'
},
output: {
path: 'build',
filename: '[name].js' // 模版基于上边 entry 的 key
}
};
针对 profile, 在页面当中插入 <script src="build/Profile.js"></script>. feed 页面也是一样.
8. 优化共用代码
feed 页面跟 profile 页面共用不要代码(比如 React 还有通用的样式和 component). Webpack 可以分析出来他们有多少共用模块, 然后生成一个共享的包用于代码的缓存.
// webpack.config.js
var webpack = require('webpack');
var commonsPlugin =
new webpack.optimize.CommonsChunkPlugin('common.js');
mole.exports = {
entry: {
Profile: './profile.js',
Feed: './feed.js'
},
output: {
path: 'build',
filename: '[name].js'
},
plugins: [commonsPlugin]
};
在上一个步骤的 script 标签前面加上 <script src="build/common.js"></script> 你就能得到廉价的缓存了.
9. 异步加载
CommonJS 是同步的, 但是 Webpack 提供了异步指定依赖的方案. 这对于客户端的路由很有用, 你想要在每个页面都有路由, 但你又不像在真的用到功能之前就下载某个功能的代码.
声明你想要异步加载的那个"分界点". 比如:
if (window.location.pathname === '/feed') {
showLoadingState();
require.ensure([], function() { // 语法奇葩, 但是有用
hideLoadingState();
require('./feed').show(); // 函数调用后, 模块保证在同步请求下可用
});
} else if (window.location.pathname === '/profile') {
showLoadingState();
require.ensure([], function() {
hideLoadingState();
require('./profile').show();
});
}
Webpack 会完成其余的工作, 生成额外的 chunk 文件帮你加载好.
Webpack 在 HTML script 标签中加载他们时会假设这些文件是怎你的根路径下. 你可以用 output.publicPath 来配置.
// webpack.config.js
output: {
path: "/home/proj/public/assets", // path 指向 Webpack 编译能的资源位置
publicPath: "/assets/" // 引用你的文件时考虑使用的地址
10. js异步加载的callback()方法是怎么回事
上面的来callback()方法是参数传入的源,当然需要你在外部定义一个函数。
回调函数,就是当加载完成后,可以进行下一步操作的函数。
举个简单的例子:
登陆操作,当输入用户名和密码进行登陆后,发送一个异步请求至服务端,来验证是否为合法用户。
假如服务端的验证方法,返回一个true|false的布尔值。
客户端脚本中在得到服务端的响应后,就可以进入回调函数。
那么在回调函数中,可以根据这个返回值,进行相应的操作。比如,true的话,跳转到主页面;false的话,重新定位到登陆页面。
回调函数在ajax中还是很有用的。