手机号已绑定微信取消绑定手机号号怎么可以登上手机号

您目前使用的浏览器该进博物馆啦~~~
为了更佳的浏览体验,请使用现代浏览器访问本站
Outdated Browser
您的浏览器已禁用 Javascript,启用它获得更好的体验。
Outdated Browser
这是为桌面用户准备的工具,但您可以安心在这里浏览
46.5% 的互联网用户在使用 此款浏览器
GOOGLE CHROME
支持如下操作系统
16.5% 的互联网用户在使用 此款浏览器
MOZILLA FIREFOX
支持如下操作系统
21.6% 的互联网用户在使用 此款浏览器
INTERNET EXPLORER
支持如下操作系统
10.3% 的互联网用户在使用 此款浏览器
APPLE SAFARI
支持如下操作系统
1.5% 的互联网用户在使用 此款浏览器
支持如下操作系统
冷静 这是为桌面用户提供的不是为手机用户提供的webpack安装配置使用教程详解-linux-操作系统-壹聚教程网webpack安装配置使用教程详解
本文章来为各位详细的介绍一下关于webpack安装配置使用教程吧,这篇文章对于不喜欢使用 jspm测试的朋友可以参考一下。
webpack 入门
1 安装 webpack
2 初始化项目
3 webpack 配置
4 自动刷新
5 第三方库
7 打包、构建
8 webpack 模板
我最近大量使用的是 jspm,但因为用它搭建的前端开发环境中,写测试代码非常困难,而项目又需要写测试,所以决定先试试 webpack。
安装 webpack
webpack 是一个 npm 包,所以我们通过 npm 命令来全局安装:
npm install webpack -g
安装完成后,命令行下就有 webpack 命令可用,执行 webpack --help 可以查看 webpack 提供的各种命令。
初始化项目
grunt.js 一类工具可以借助 yeoman 来初始化项目,目前我并没有看到 webpack 有类似方法,所以当 node.js 项目来初始化。
npm init 创建一个 package.json 文件
npm install webpack --save-dev 在当前目录下安装局域的 webpack
完成以上两个步骤后,我们的项目下有一个 package.json 文件,一个 node_modules 文件夹,我们还需要一个 index.html 文件,内容如下:
&!DOCTYPE html&
&html lang=&en&&
&&& &meta charset=&UTF-8&&
&&& &title&webpack 教程&/title&
webpack 配置
我们的代码将组织在 JavaScript 模块中,项目会有一个入口(entry)文件,比如 main.js,我们需要通过 webpack 的配置文件指明它的位置。
在根目录新建一个 webpack.config.js 文件,添加如下内容:
module.exports = {
& entry: './main.js'
因为我们在项目部署前需要打包合并 js 文件,所以还需要在 webpack.config.js 中配置一个 output:
module.exports = {
&&& entry: './main.js',
&&& output: {
&&&&&&& path: __dirname,
&&&&&&& filename: 'bundle.js'
output 定义我们打包出来的文件位置及名称。
完成以上后,试着在项目根目录下执行 webpack 命令,我们的根目录下会多出一个 bundle.js 文件:
&webpack build
到现在为止,我们还没在浏览器中打开 index.html 文件,实际上,我们连 bundle.js 文件都还没加入 index.html 文件中。现在且先加入:
&!DOCTYPE html&
&html lang=&en&&
&&& &meta charset=&UTF-8&&
&&& &title&webpack 教程&/title&
& &script src=&./bundle.js&&&/script& &!-- 在 index.html 文件中添加这一行代码 --&
这是 webpack 异于其它工具的地方,它在 HTML 文件中直接引用了 build 后的 js 文件,而不是原始的 main.js 文件。这就会有几个问题:
Q: main.js 或它所引用的模块的变化如何实时编译到 bundle.js?
A: 非常简单,在根目录下执行 webpack --watch 就可以监控文件变化并实时编译了
Q: 上面只是实时编译了 js 文件,我们该如何把变化同步到浏览器页面上,实现实时刷新?
A: webpack 提供了 webpack-dev-server 解决实时的问题,同时解决上面一个问题。
安装 webpack-dev-server
执行 npm install webpack-dev-server -g 在全局环境中安装 webpack-dev-server
在项目根目录下执行命令:
$ webpack-dev-server
这样,我们就可以在默认的 http://localhost:8080 网址上打开我们的项目文件了。
此时,我们可能会认为,
js 文件修改
webpack-dev-server 监控到变化
webpack 重新编译
实时更新浏览器中的页面
但不幸的是,我们「自以为是」了。http://localhost:8080 这个网站对 js 文件的变化无动于衷。
我们可以启用 webpack-dev-server 的 hot 模式,在代码中插入如下一行:
&script src=&http://localhost:8080/webpack-dev-server.js&&&/script&
这样 http://localhost:8080/ 这个网址也可以根据 js 的变化相应地自动刷新了。
webpack 并不是包管理器,所以如果我们要使用第三方库,则需要借助 npm 或其它工具。比如,在项目里安装 jQuery:
npm install jquery --save
webpack 自称 module bundler,在它的定义中,CSS、图片、文件等等,都可以通过相应的 loader 加载,变成 JavaScript模块,以下具体展开说明。
模块化 JavaScript
如果我想使用 ES6 的方式引入某个 es6 模块,比如:
import $ from 'whatever';
怎么办?浏览器并不提供原生支持,webpack 通过各种 loader 来解决这类问题。比如这 ES6 的语法,可以借助 babel-loader:
安装 babel-loader
npm install --save-dev babel-loader
配置 webpack.config.js
在 module.exports 值中添加 module:
module.exports = {
&&& app: ['webpack/hot/dev-server', './main.js']
&&& filename: 'bundle.js'
&&& loaders: [
&&&&&&& { test: /\.js$/, loader: 'babel', exclude: /node_modules/ }
这样我们就可以在我们的 js 文件中使用 ES6 语法,babel-loader 会负责编译。
上面的方法,是在 webpack.config.js 文件中定义某一类型文件的加载器,我们也可以在代码中直接指定:
import $ from 'babel!whatever'
因为 babel-loader 允许我们使用 ES6 语法,于是我们的模块完全可以用 ES6 的 module 来组织代码: export 一个简单的模块:
// script/log.js 文件
export default (param) =& {
&&& console.log('你好啊', param);
然后在 main.js 中导入使用:
// main.js 文件
import log from &./script/log.js&;
CSS 加载器
我们可以按传统方法使用 CSS,即在 HTML 文件中添加:
&link rel=&stylesheet& href=&style/app.css&&
但 webpack 里,CSS 同样可以模块化,然后使用 import 导入。
因此我们不再使用 link 标签来引用 CSS,而是通过 webpack 的 style-loader 及 css-loader。前者将 css 文件以 &style&&/style& 标签插入 &head& 头部,后者负责解读、加载 CSS 文件。
安装 CSS 相关的加载器
npm install style-loader css-loader --save-dev
配置 webpack.config.js 文件
&&& loaders: [
&&&&&&& { test: /\.css$/, loaders: ['style', 'css'] }
在 main.js 文件中引入 css
import'./style/app.css';
重启 webpack-dev-server
模块化 CSS
上一步里,我们 import 到 JavaScript 文件中的 CSS 文件中的 CSS 类打包时是 export 到全局环境的,也就是说,我们只是换了种加载 CSS 的方式,在书写 CSS 的时候,还是需要注意使用命名规范,比如 BEM,否则全局环境 CSS 类的冲突等问题不会消失。
这里,webpack 做了一个模块化 CSS 的尝试,真正意思上的「模块化」,即 CSS 类不会泄露到全局环境中,而只会定义在 UI 模块内 & 比如 react.js 这类模块,或者 web components。类似的尝试还有 ember-component-css 与 jspm 的 plugin css。
autoprefixer
我们在书写 CSS 时,按规范写,构建时利用 autoprefixer 可以输出 -webkit、-moz 这样的浏览器前缀,webpack 同样是通过 loader 提供该功能。
安装 autoprefixer-loader
npm install autoprefixer-loader --save-dev
配置 webpack.config.js
loaders: [{
loader: 'style!css!autoprefixer?{browsers:[&last 2 version&, && 1%&]}',
重启 webpack-dev-server
假如我们在 CSS 中写了 body { display: } 规则,再查看 bundle.js 文件的话,我们能看到类似如下的代码:
body {\n\tdisplay: -webkit-\n\tdisplay: -webkit-\n\tdisplay: -ms-\n\tdisplay:\n}
图片同样可是是模块,但使用的是 file loader 或者 url loader,后者会根据定义的大小范围来判断是否使用 data url。
import loadingIMG from 'file!../img/loading.gif'
React.render(&img src={loadingIMG} /&, document.getElementById('app'));
打包、构建
项目结束后,代码要压缩、混淆、合并等,只需要在命令行执行:
即可,webpack 根据 webpack.config.js 文件中的配置路径、构建文件名生成相应的文件。
webpack 模板
上面说的是一步一步使用 webpack 搭建开发环境,当然,实际应用中,大可以借用一些模板,比如 react hot boilerplate 这样的库。
上一页: &&&&&下一页:相关内容
暂无与此文章相关内容最新内容一小时包教会 —— webpack 入门指南-爱编程
一小时包教会 —— webpack 入门指南
什么是 webpack?
webpack是近期最火的一款模块加载器兼打包工具,它能把各种资源,例如JS(含JSX)、coffee、样式(含less/sass)、图片等都作为模块来使用和处理。
我们可以直接使用 require(XXX) 的形式来引入各模块,即使它们可能需要经过编译(比如JSX和sass),但我们无须在上面花费太多心思,因为 webpack 有着各种健全的加载器(loader)在默默处理这些事情,这块我们后续会提到。
你可以不打算将其用在你的项目上,但没有理由不去掌握它,因为以近期 Github 上各大主流的(React相关)项目来说,它们仓库上所展示的示例已经是基于 webpack 来开发的,比如 React-Boostrap 和 Redux。
webpack的官网是
,文档地址是
,想对其进行更详细了解的可以点进去瞧一瞧。
webpack 的优势
其优势主要可以归类为如下几个:
1. webpack 是以 commonJS 的形式来书写脚本滴,但对 AMD/CMD 的支持也很全面,方便旧项目进行代码迁移。
2. 能被模块化的不仅仅是 JS 了。
3. 开发便捷,能替代部分 grunt/gulp 的工作,比如打包、压缩混淆、图片转base64等。
4. 扩展性强,插件机制完善,特别是支持 React 热插拔(见
)的功能让人眼前一亮。
我们谈谈第一点。以 AMD/CMD 模式来说,鉴于模块是异步加载的,所以我们常规需要使用 define 函数来帮我们搞回调:
define(['package/lib'], function(lib){
function foo(){
lib.log('hello world!');
另外为了可以兼容 commonJS 的写法,我们也可以将 define 这么写:
define(function (require, exports, module){
var someModule = require("someModule");
var anotherModule = require("anotherModule");
someModule.doTehAwesome();
anotherModule.doMoarAwesome();
exports.asplode = function (){
someModule.doTehAwesome();
anotherModule.doMoarAwesome();
然而对 webpack 来说,我们可以直接在上面书写 commonJS 形式的语法,无须任何 define (毕竟最终模块都打包在一起,webpack 也会最终自动加上自己的加载器):
var someModule = require("someModule");
var anotherModule = require("anotherModule");
someModule.doTehAwesome();
anotherModule.doMoarAwesome();
exports.asplode = function (){
someModule.doTehAwesome();
anotherModule.doMoarAwesome();
这样撸码自然更简单,跟回调神马的说 byebye~
不过即使你保留了之前 define 的写法也是可以滴,毕竟 webpack 的兼容性相当出色,方便你旧项目的模块直接迁移过来。
安装和配置
我们常规直接使用 npm 的形式来安装:
$ npm install webpack -g
当然如果常规项目还是把依赖写入 package.json 包去更人性化:
$ npm init
$ npm install webpack --save-dev
每个项目下都必须配置有一个 webpack.config.js ,它的作用如同常规的 gulpfile.js/Gruntfile.js ,就是一个配置项,告诉 webpack 它需要做什么。
我们看看下方的示例:
var webpack = require('webpack');
var commonsPlugin = new monsChunkPlugin('common.js');
module.exports = {
plugins: [commonsPlugin],
//页面入口文件配置
index : './src/js/page/index.js'
//入口文件输出配置
path: 'dist/js/page',
filename: '[name].js'
//加载器配置
loaders: [
{ test: /\.css$/, loader: 'style-loader!css-loader' },
{ test: /\.js$/, loader: 'jsx-loader?harmony' },
{ test: /\.scss$/, loader: 'style!css!sass?sourceMap'},
{ test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192'}
//其它解决方案配置
resolve: {
root: 'E:/github/flux-example/src', //绝对路径
extensions: ['', '.js', '.json', '.scss'],
AppStore : 'js/stores/AppStores.js',
ActionType : 'js/actions/ActionType.js',
AppAction : 'js/actions/AppAction.js'
⑴ plugins 是插件项,这里我们使用了一个 CommonsChunkPlugin&的插件,它用于提取多个入口文件的公共脚本部分,然后生成一个 common.js 来方便多页面之间进行复用。
⑵ entry 是页面入口文件配置,output 是对应输出项配置(即入口文件最终要生成什么名字的文件、存放到哪里),其语法大致为:
page1: "./page1",
//支持数组形式,将加载数组中的所有模块,但以最后一个模块作为输出
page2: ["./entry1", "./entry2"]
path: "dist/js/page",
filename: "[name].bundle.js"
该段代码最终会生成一个 page1.bundle.js 和 page2.bundle.js,并存放到 ./dist/js/page 文件夹下。
⑶ module.loaders 是最关键的一块配置。它告知 webpack 每一种文件都需要使用什么加载器来处理:
//加载器配置
loaders: [
//.css 文件使用 style-loader 和 css-loader 来处理
{ test: /\.css$/, loader: 'style-loader!css-loader' },
//.js 文件使用 jsx-loader 来编译处理
{ test: /\.js$/, loader: 'jsx-loader?harmony' },
//.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'}
如上,"-loader"其实是可以省略不写的,多个loader之间用“!”连接起来。
注意所有的加载器都需要通过 npm 来加载,并建议查阅它们对应的 readme 来看看如何使用。
拿最后一个
来说,它会将样式中引用到的图片转为模块来处理,使用该加载器需要先进行安装:
npm install url-loader -save-dev
配置信息的参数“?limit=8192”表示将所有小于8kb的图片都转为base64形式(其实应该说超过8kb的才使用 url-loader 来映射到文件,否则转为data url形式)。
⑷ 最后是 resolve 配置,这块很好理解,直接写注释了:
resolve: {
//查找module的话从这里开始查找
root: 'E:/github/flux-example/src', //绝对路径
//自动扩展文件后缀名,意味着我们require模块可以省略不写后缀名
extensions: ['', '.js', '.json', '.scss'],
//模块别名定义,方便后续直接引用别名,无须多写长长的地址
AppStore : 'js/stores/AppStores.js',//后续直接 require('AppStore') 即可
ActionType : 'js/actions/ActionType.js',
AppAction : 'js/actions/AppAction.js'
关于 webpack.config.js 更详尽的配置可以参考。
运行 webpack
webpack 的执行也很简单,直接执行
$ webpack --display-error-details
即可,后面的参数“--display-error-details”是推荐加上的,方便出错时能查阅更详尽的信息(比如 webpack 寻找模块的过程),从而更好定位到问题。
其他主要的参数有:
$ webpack --config XXX.js
//使用另一份配置文件(比如webpack.config2.js)来打包
$ webpack --watch
//监听变动并自动打包
$ webpack -p
//压缩混淆脚本,这个非常非常重要!
$ webpack -d
//生成map映射文件,告知哪些模块被最终打包到哪里了
其中的 -p 是很重要的参数,曾经一个未压缩的 700kb 的文件,压缩后直接降到 180kb(主要是样式这块一句就独占一行脚本,导致未压缩脚本变得很大)。
上面唠嗑了那么多配置和执行方法,下面开始说说寻常页面和脚本怎么使用呗。
直接在页面引入 webpack 最终生成的页面脚本即可,不用再写什么 data-main 或&seajs.use 了:
&!DOCTYPE html&
&head lang="en"&
&meta charset="UTF-8"&
&title&demo&/title&
&script src="dist/js/page/common.js"&&/script&
&script src="dist/js/page/index.js"&&/script&
可以看到我们连样式都不用引入,毕竟脚本执行时会动态生成&style&并标签打到head里。
各脚本模块可以直接使用 commonJS 来书写,并可以直接引入未经编译的模块,比如 JSX、sass、coffee等(只要你在 webpack.config.js 里配置好了对应的加载器)。
我们再看看编译前的页面入口文件(index.js):
require('../../css/reset.scss'); //加载初始化样式
require('../../css/allComponent.scss'); //加载组件样式
var React = require('react');
var AppWrap = require('../component/AppWrap'); //加载组件
var createRedux = require('redux').createR
var Provider = require('redux/react').P
var stores = require('AppStore');
var redux = createRedux(stores);
var App = React.createClass({
render: function() {
&Provider redux={redux}&
{function() { return &AppWrap /&; }}
&/Provider&
React.render(
&App /&, document.body
一切就是这么简单么么哒~ 后续各种有的没的,webpack 都会帮你进行处理。
至此我们已经基本上手了 webpack 的使用,下面是补充一些有用的技巧。
一. shimming
在 AMD/CMD 中,我们需要对不符合规范的模块(比如一些直接返回全局变量的插件)进行 shim 处理,这时候我们需要使用& 来帮忙:
{ test: require.resolve("./src/js/tool/swipe.js"),
loader: "exports?swipe"}
之后在脚本中需要引用该模块的时候,这么简单地来使用就可以了:
require('./tool/swipe.js');
二. 自定义公共模块提取
在文章开始我们使用了&CommonsChunkPlugin 插件来提取多个页面之间的公共模块,并将该模块打包为 common.js 。
但有时候我们希望能更加个性化一些,我们可以这样配置:
var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin");
module.exports = {
p1: "./page1",
p2: "./page2",
p3: "./page3",
ap1: "./admin/page1",
ap2: "./admin/page2"
filename: "[name].js"
plugins: [
new CommonsChunkPlugin("admin-commons.js", ["ap1", "ap2"]),
new CommonsChunkPlugin("commons.js", ["p1", "p2", "admin-commons.js"])
// &script&s required:
// page1.html: commons.js, p1.js
// page2.html: commons.js, p2.js
// page3.html: p3.js
// admin-page1.html: commons.js, admin-commons.js, ap1.js
// admin-page2.html: commons.js, admin-commons.js, ap2.js
三. 独立打包样式文件
有时候可能希望项目的样式能不要被打包到脚本中,而是独立出来作为.css,然后在页面中以&link&标签引入。这时候我们需要& 来帮忙:
var webpack = require('webpack');
var commonsPlugin = new monsChunkPlugin('common.js');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
plugins: [commonsPlugin, new ExtractTextPlugin("[name].css")],
//...省略其它配置
最终 webpack 执行后会乖乖地把样式文件提取出来:
四. 使用CDN/远程文件
有时候我们希望某些模块走CDN并以&script&的形式挂载到页面上来加载,但又希望能在 webpack 的模块中使用上。
这时候我们可以在配置文件里使用&externals 属性来帮忙:
externals: {
// require("jquery") 是引用自外部模块的
// 对应全局变量 jQuery
"jquery": "jQuery"
需要留意的是,得确保 CDN 文件必须在 webpack 打包文件引入之前先引入。
我们倒也可以使用&&在脚本中来加载我们的模块:
var $script = require("scriptjs");
$script("///ajax/libs/jquery/2.0.0/jquery.min.js", function() {
$('body').html('It works!')
五. 与 grunt/gulp 配合
以 gulp 为示例,我们可以这样混搭:
gulp.task("webpack", function(callback) {
// run webpack
// configuration
}, function(err, stats) {
if(err) throw new gutil.PluginError("webpack", err);
gutil.log("[webpack]", stats.toString({
// output options
callback();
当然我们只需要把配置写到 webpack({ ... }) 中去即可,无须再写 webpack.config.js 了。
更多参照信息请参阅: /
六. React 相关
⑴ 推荐使用 npm install react 的形式来安装并引用 React 模块,而不是直接使用编译后的 react.js,这样最终编译出来的 React 部分的脚本会减少 10-20 kb左右的大小。
⑵&&是一款非常好用的 React 热插拔的加载插件,通过它可以实现修改-运行同步的效果,配合& 使用更佳!
基于 webpack 的入门指引就到这里,希望本文能对你有所帮助,你也可以参考下述的文章来入门:
版权所有 爱编程 (C) Copyright 2012. . All Rights Reserved.
闽ICP备号-3
微信扫一扫关注爱编程,每天为您推送一篇经典技术文章。标签:至少1个,最多5个
在目前的开源市场,前端架构中最火热的项目非webpack莫属了。在使用webpack的过程中,我们会用到各式各样的loader,毫无疑问,因为loader机制的存在让webpack拥有了无限的可能性,让webpack几乎可以容纳一切前端需要的资源。同时合理得利用loader也有助于我们在架构项目的时候省去很多重复工作,今天我们就来讲讲如何创建一个webpack的loader
在最开始想到要写loader的时候,其实我是拒绝的,因为webpack主要的功能是处理依赖以及编译,一提到编译我就头疼,各种字符串处理能让我上天。然而进一步了解之后我发现我想多了,大部分的时候编译的工作并不需要你来做,不多讲,看代码。
首先你需要知道如何调试你本地的loader,幸运的是,不管是在webpack.config.js中写相对路径还是直接require('./loader-name!&file path&')webpack都是可以访问到我们的本地loader的,所以这点无需担心
其次一个loader就是一个方法,这个方法接受一个source参数包括指定文件的内容,this包含了很多webpack的方法和属性供调用,该方法需要将你处理之后的内容返回,如果有sourcemap,也可以一并将sourcemap返回,这个时候需要调用this.callback(null, source, map),第一个null代表没有错误,如果有错误的话就是一个Error对象
所以一个loader大致长成这样
module.exports = function (source) {
if (cacheable) this.cacheable()
// do something about the source
return dealedSource // 返回处理过的source
// this.callback(null, dealedSource, map) // 如果有sourcemap
记住cacheable那一步必须要执行,一方面他可以提高webpack除第一次之外的编译熟读,再次如果有cacheable官方推荐是必须cacheable的,实践情况也是不执行的话会有奇葩错误,这点上因为webpack了解不深,同时也没有相关文档,所以不是很了解清楚(你知道webpack的源码多大么!!!!!)
然后其实该讲的就已经讲完了。。。因为loader里面的处理逻辑是根据你的实际情况来的,这没什么好说的,比如less-loader里面就是调用了less把source处理一下然后return出去,所以想到什么的朋友应该已经可以动手写自己的loader了
好吧,再说点什么在我遇到情况中,我需要在vue-loader之前做一些特定操作(通过demo生成文档),所以我先去研究了一下vue-loader的源码。vue-loader的操作逻辑我会重新起一片文章讲,到时候我再贴过来,我只想抱怨一下vue-loader真是一个大坑,因为vue-loader实际上调用两次文件的source,所以你在vue-loader之前对source做的任何操作都是没什么卵用,我了一整晚/(ㄒoㄒ)/~~
吐槽来了,
但在这种情况下,还是有办法处理,只是感觉有点hacker,并不是那么好,所以webpack得loader还是可以发挥你的很多想象力的。就酱,回家吃饭~~~
--------------- 4-15日补充 ----------------发现一个重点,那就是如果你的loader处理的文件有依赖于别的文件,你必须在loader里面生命Dependency,不然的话很容易出现内容不更新等情况
0 收藏&&|&&6
你可能感兴趣的文章
16 收藏,2.8k
30 收藏,5k
43 收藏,5.3k
本作品采用 署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可
分享到微博?
你好!看起来你挺喜欢这个内容,但是你还没有注册帐号。 当你创建了帐号,我们能准确地追踪你关注的问题,在有新答案或内容的时候收到网页和邮件通知。还能直接向作者咨询更多细节。如果上面的内容有帮助,记得点赞 (????)? 表示感谢。
明天提醒我
我要该,理由是:
扫扫下载 AppWebpack从入门到上线
webpack是目前一个很热门的前端打包工具,官网说得很清楚,webpack的出现就是要把requirejs干掉。同时它还提供了十分便利的本地开发的环境。网上并不容易找到一个讲解得比较详细完整的教程,本文结合实践经验,总结一套可用的开发和上线的配置和流程。首先,Require JS有什么问题RequireJs存在的问题博主先是使用了RequireJs,后来又转了webpack,综合比较,requirejs确实存在一些缺点:1.写法比较笨拙需要把所有的依赖模块写在require函数里面,当模块很多的时候,看起来逼格就不高了,感受如下:而webpack既兼容requirejs的写法,也兼容commonjs的写法,也就是说,使用webpack你既可以继续像上面那样写,也可以像node那样写,感受如下:可以在需要的时候再去require,而不是搞个大括号把全部的模块一下子写到一起。(模块的导出用module.exports = ….)当然这两种写法不仅是感光上的区别,逻辑上也有区别。用中括号加载的模块通常webpack是动态去加载,而没有中括号是和主文件打包在一起的。2. 没有通用模块的概念例如有一个弹框模块,用在登陆注册,并且所有页面都有登陆注册,所以这是一个所有页面的通用模块。如果页面的其它模块都没调到通用模块里面的东西的话,用RequireJs没什么问题。但是实际情况上不是这样的,例如util模块既会被登陆注册的模块调用,也会被很多其它模块调用。这个时候合并压缩就有问题了:合并后的通用模块如common-app.js会带上util的代码、另外一个页面的例如detail.js也会带上util的代码,以后一改util.js里面的东西,就会一并改动其它所有用到util的页面js,就得重新打所有js的版本号。这样无论对布署上线,还是对于用户的缓存来说都是不利的。webpack可以把几个文件的通用模块抽出来单独作为一个模块common-chunk.js,引用的时候每个页面先引一个common-chunk.js,再引一个该页面自己的js文件如detail.js,原detail.js里面和其它js文件共用的模块已经被提取到common-chunk.js里面。3. 没办法直接动态合并压缩一个需要异步加载的模块这个问题是这样的,假设我的聊天模块文件有500Kb这么大,并不希望一刷页面就加载,而是用户点了聊天再去加载。这个聊天模块有一个入口文件和其它几个模块文件,我合并压缩了入口文件,需要有一个输出文件,而入口文件define的模块名和压缩优化后的输出文件的路径肯定是要不一样的,但是压缩之后他并不会自动去改变输出文件的模块名。这样就导致你要手动去改一下压缩文件的模块名,不然会require不到。我之前找了一下,没有找到解决方案,所以采取了一个压缩两次的比较笨拙的方法。而webpack有一个文件束chunkFile的概念,它会自动去把需要异步加载的文件变成一个chunkFile,然后触发加载的时候再去加载chunkFile。4. 需要借助gulp等管理工具进行开发webpack本身有一些插件和第三方的插件,可以在本地开一个webpack-dev-server,文件一保存的时候就会自动打包编译js/css/less/sass等。使用RequireJs虽然看起来缺点比较多,但是使用RequireJs也有webpack不具备的优点,那就是RequireJs开发的时候在浏览器里面,每个模块都是单独一个文件,跟本地文件保持一致,而webpack是把主文件和该文件都用到的模块都打包成了一个文件,这样在调试的时候就需要你去搜索找到要调试的位置,而使用requireJs直接根据第几行就可以了。不过,考虑到使用webpack可以搭建一个很方便的本地开发环境,所以这个缺点也不是很明显。使用webpack用一句概括就是:写一个配置文件,然后执行下webpack,就可以把生成的文件输出,可压缩带版本号,同时生成一个source-map文件,这个文件包含了每个模块的js和css的实际(带版本号)路径,根据这个路径就可以把html里面的js/css等换成真实的路径。webpack是一个打包的工具,它有一个重要的概念,就是把js/css/image/coffee都当成地位相等的资源,你可以在js里面require一个css,也可以require一个image。但是这种模式比较适用于React等框架,都是用js控制。webpack的其它几个重要概念:1. loader加载器上面说到,各种各样的资源都可以在webpack里面加载,而这些资源都需要相应的加载器,webpack才能识别,然后解析成正常的浏览器认识的资源。换句话说,你可以给webpack加载各种各样的资源:css/less/sass/png/babel等,然后在代码里面进行管理。例如要加一个sass的loader,需要先安装:然后在配置文件添加一个loader:这样当你require(“hello.sass”)的时候,webpack就能处理这种.sass结尾的文件。这样子有两个好处,一个是webpack能够自动编译sass为css,另一个是require进来的style,webpack会把它解析成一个object,这个object的key就是类名,就可以在js使用样式的类名,这种比较适合类似于react的开发模式。2. 文件束chunk上面提到的,会把动态加载的文件生成一个个的chunk,在配置文件的output里面加一行:就会根据id区分不同动态加载的chunk文件,而这些chunk文件名对于我们来说是无关紧要,因为这个是webpack管理的,开发者无需关心叫什么又是怎么加载的。3. webpack-dev-server这是webpack的一个插件,可以在本地开一个静态服务,用来作为本地开发的重要工具。具体步骤就是html里面引用的资源用一个假的域名,如:然后再把绑到本地回路:127.0.0.这样请求就打到了本地的80端口。同时在本地开一个nginx监听在80端口,nginx收到80端口的请求后,再把请求转发到webpack的服务(默认是8080端口)。这样就能够实现本地开发,下文会具体介绍。下面一步步介绍怎么配置和使用webpackwebpack的基本配置首先,npm init创建一个node的配置文件package.json,然后安装webpack:再创建一个webpack.config.js文件,加入最基本的配置:工程的js都放到js目录下,一个叫home.js,另一个叫detail.js,输出到assets目录,publicPath是为webpack-dev-server所使用然后在当前目录执行webpack,发现webpack报错了:ERROR in Entry module not found: Error: Cannot resolve module ‘js/home’ in /Users/yincheng/code/blog-webpack找不到js/home的模块,只要在配置里面加一句resolve:告诉webpack所有模块的启始目录由当前目录开始,再执行下webpack就可以正常输出了:到目前为此,当前工程的目录结构就是这样的了:接下来,创建html:home.html,里面引入js文件,”static/build”即为上面定义的publicPath:注意我们用了一个的域名,把这个域名绑到本地回路:然后配置nginx,打开nginx.conf,加多一个server:启动nginx或者重启下nginx然后再装一个webpack-dev-server:然后启动webpack-dev-server,执行:然后就可以访问:/html/home.html这个时候,只要一改变home.js的内容,webpack-dev-server就会自动打包新的文件 ,一刷新页面,就是最新的修改了。这样就实现了最基本的本地开发,不管你用的jsp/php,都不需要把js/css往服务器上传。 注意webpack-dev-server是在内存生成的文件,你在本地是找不到static/build目录的,只有执行了webpack打包才会输出文件到assets目录。一个为上面配置里的publicPath,另一个为path。引入样式文件——首先创建css/home.css:然后在js里面引入这个css文件:一保存之后,会发现webpack-dev-server报错了:ERROR in ./css/home.css Module parse failed: /Users/yincheng/code/blog-webpack/css/home.css Unexpected token (1:4) You may need an appropriate loader to handle this file type.根据提示,我们需要加装一个css loader,让webpack能够处理css文件,更改webpack.config.js,加入一个loader:当然要先安装一下:npm install style-loader css-loader –save-dev,然后再重启下webpack-dev-server,就可以加载样式了,我们发现webpack是把样式动态插到了head标签的style里面,但是一般并不希望直接写到head里面,而是独立的一个css文件,这个时候借助一个分离css的插件就可以了:同时把配置文件的loader改一下:就会生成和js相同路径和名字的css文件,在home.html里面引入css文件:你也可以加载各种各样的loader,如加载一个sass/less loader,require一个sass/less文件后就可以写sass/less了,webpack会把它编译成和上面一样普通的css文件,读者可以自己试试,还可以再装一个png/jpg的loader,指定一个小于多少个k的图片的参数,webpack就会把小于指定尺寸的图片转成base64的格式。各种loader的安装查一查就有了。到这里一个最基本的本地开发环境就已经搭起来了。接下来讨论自动刷新自动刷新上面一保存js/css的时候,webpack server就会自动打包,刷新页面的时候就是最新的修改。这个刷新只要使用webpack的hot模式就可以自动实现,即一保存就自动打包刷新。将上面运行webpack-dev-server的命令再加多两个参数,按照官方文档的方式:这个问题困惑了笔者好久,因为在node_modules里面是有这个”webpack/hot/dev-server”的,其实只要认真看下上面的提示,就会发现它并不是说在node_modules里面,而是在当前工程目录里,所以把node_modules里的webpack文件夹拷一份到外面就可以正常运行了。(如果你又配了个context的参数的话,那就根据提示拷到context指定的目录)使用hot模式,只要一保存js/css就可以自动刷新了,这个功能确实很方便。如果不写参数,也可以把它写在配置文件里面:然后运行server就不用带上后面那两个参数了。Common chunk如上文提到,webpack可以将几个js的公共模块提取成一个chunk,需要借助一个commonChunkPlugin,在上面的plugins再添加一个:这样就可以把home、detail、list三个js和css用到的公共模块提取到common-app.chunk.js和common-app.chunk.css这两个文件了。注意页面要先引入这两个文件,然后再引入具体页面的js,webpack在common chunk里面定义了它的require函数。如上面的home.html:可以指定一个minChunk的参数,指定模块至少被require几次才能提取出来,默认是3还可以定义两个commonChunk,例如在详情页、列表页和首页都有搜索的模块,而其它页面没有搜索的模块,也就是说除了所有页面都有的公共模块如登陆注册外,还有一个搜索的公共模块有三个页面要用到。如果都用一个common chunk,会把搜索的也放进来,但其它很多页面并不需要用到。这个时候需要加多一个common chunk:注意要把search-app.chunk也写到下面那个所有页面的chunk里面,否则webpack会定义两个一样的require函数,页面的模块也会跟着混乱,一刷页面就报错。页面引用js的顺序就变成了:压缩和版本号压缩只需要要在plugins里面再添加一个用来压缩的插件:这样执行webpack输出的js/css就是压缩的版本号就是在输出带上hash的替换符,如下:其中js用的是webpack的chunkhash,而css用的是contenthash,contenthash是根据内容生成的hash。如果不用contenthash,那么一改js,css的版本号也会跟着改变,这个就有问题了。webpack还有另外一个自带的叫做”[hash]”,这个hash是所有文件都用的同一个哈希,也就是说某个文件改了,所有文件的版本号都会跟着改,所以一般不用这个。运行webpack,如果报了下面这个错误:ERROR in chunk detail [entry] [name]-[chunkhash].js Cannot use [chunkhash] for chunk in ‘[name]-[chunkhash].js’ (use [hash] instead)那你就把plugins里面的热替换插件注释掉就好了,上线的config不需要热替换:成功执行后,就会在设定的output目录下面输出加上版本号的文件:├── detail-d19ef3c1581b.js├── home-4e8c58ce10a.css└── home-5ec13a52eea2a6faf96a.js有了版本号之后,下一步是要把html里面的js/css换成带版本号的路径替换Html里js/css路径之前在html里的路径是,现在要把它换成cdn且带版本号的路径,也就是说,目标是要把下面的引入:替换成下面的引入,并把新生成的html输出到built目录目测没有现成符合格式的插件可以用,可以自已用node写一个,不费事。首先要知道所有文件的对应的版本号,可以用AssetsPlugin,生成source-map:执行webpack之后,就会生成source-map.json,打开这个文件:根据开头的以及最后面的home.js/home.css,就可以在上面找到对应的路径名。笔者写了个脚本,可以实现这个功能,详见:/liyincheng/version-control-replace-html到这里,整个流程就基本完成了。还有一些优化的步骤优化1. 优化模块idwebpack对于每个模块都是用id标志,而不是用模块的名字,只是为了节省空间。还可以再节省,就是用它自带的occurrence-order插件将最常用的模块靠前,这样可以再节省一点点空间,因为id是从0开始排的,从一位数到n位数。new webpack.optimize.OccurenceOrderPlugin()2. 移出版本号在上面用了common-chunk的插件,抽离公共模块,在这个common-chunk.js里,webpack会定义每个模块加载的src,以便于加载那些需要动态加载的chunk,如下:script.src = webpack_require.p + “” + chunkId + “-“ + {“0”:”0cb48ff1ab1d1156015d”,”5”:”e9e7f761f306c648ccef”,”6”:”cbbdf8e3ad1aba34ced0”}[chunkId] + “.js”;从上面可以看出它会把版本号也写在里面,这样就导致一个问题,每改一个js文件,它的版本号就会变化,就会导致common chunk里面的内容发生变化,所以它的版本号也得跟着变,也就是说改了一个文件,影响了两个文件。所以需要把它抽出来,有个插件已经做了这样的事情,叫做ChunkManifestPlugin:传两个参数,一个是输出文件名,另一个是变量名,用于上面的script.src,执行webpack后,它会把上面script.src的那一坨东西放到chunk-manifest.json,然后在页面写一个内联的script,定义一个全局变量window.webpackManifest,值为manifest.json里面的内容。笔者已在上面的替换版本号的脚本做处理,只需在页面合适的地方写上一行:&!—%webpack manifest%—&就会把这行替换成一个script标签。3. 多个common-chunk的优化在上面写了两个common chunk,在生成的两个chunk文件里面,你会发现大量的的重复代码,已经失去了公共模块的作用,这个问题可以用一个MoveToParentMergingPlugin解决,它会把search-app用到的common-app的模块全部移到了common-app,search-app就不会重复common-app的内容了。html保存自动刷新上面提到,只要一保存css/js,webpack-dev-server就会自动保存和刷新,但是html/jsp没办法(如果你用react开发,可以用react-hot-loader),其实可以手动解决这个问题。打开node_modules/webpack-dev-server/client/index.js这个文件,可以发现webpack是用的sockjs实现自动刷新的。浏览器使用sockjs创建socket客户端,连接到webpack的服务,保存更改的时候,服务就向浏览器的socket发送消息,接收到这个消息后客户端就调window.location.reload刷新页面。所以可以模仿这个过程,在本地另开一个服务,监听html的修改,然后向浏览器端发送刷新页面的消息。具体来说,首先在上面的node_modules/webpack-dev-server/client/index.js这个文件最后面再添加一个socket连接:这个9999端口的server就是下面要在本地监听的一个socket服务。在开这个socket服务之前,需要先在本地开一个监听文件修改的服务,然后再向这个socket服务发送消息。监听的服务比较好写,有现成的node包可以用:chokidar,使用也非常简单。监听到修改之后就可以执行上传服务器的命令,然后(使用进程间的通信)再向socket服务发送一个需要刷新的消息,再传递给浏览器的scoket,如上面的代码,一收到消息就刷新页面。具体代码查看github除了优化,在使用中会遇到的一些问题:解决问题1. umd的require模式有时候会引入外部的库,这些库可能会用umd的require模式,判断是要用requirejs还是commonjs或是写个全局的函数:这个的问题就在于,只要页面上有require出现,webpack就会去打包,不管你是写if里面还click事件里面。因为像上面说的,webpack会把异步加载的文件打包成一个boundle文件,同时也会把非异步的打包到一起。像上面那样写,它会重复打包,生成好多个bundle。只要加多一个umdREquirePlugin,webpack就能正常打包了。2. 如何加载外部资源webpack是一个打包的工具,它并不是像requireJs那样可以支持直接require一个外部资源。例如我要require谷歌地图:/maps/api/js打包的时候webpack会给出一个warning,说加载不到这个外部资源,运行代码的时候会报错,提示没有这个模块。另外一个问题是,我需要if else判断,如果是中国的环境就加载中国域名的谷歌地图:/maps/api/js 否则就加载上面的,使用webpack是没办法做到的, 使用requireJs就可以很简单地直接require一下就行。但其实这个问题很好解决只要自己写一个动态加载script的函数就好了,一个兼容性很好的版本:详见:The best way to load external JavaScriptwebpack虽然是一个利器,但是坑也不少,目前遇到过的不太好解决的问题:遇到的困难1.chunkhash使用chunkhash有两个问题,一个是css改变之后,js的版本号也会跟着改变,即使js没有修改,但是比较这两个js文件的时候,你会发现这两个版本号不一样的文件内容是完全一模一样的。因为chunkhash不是根据文件内容算的hash值。第二个问题是,相同的代码在不同人的机器上打的包的版本号不一样。如果使用一些根据文件内容打版本号的插件,如webpack-md5-hash,这个插件是用文件内容作一个md5的计算得出一个版本号,这样可以解决上面的两个问题,但是又引发了新的问题,这个md5的时不时就会出现打的版本号不唯一的情况,文件内容不同、版本号相同,而且这个概率还不小。所以最后还是放弃了使用这个插件,然后又尝试了另外一个使用sha算法计算,但是这个改了一个文件会使几个文件的版本号也发生变化。现在还是使用chunkhash2.模块id发生变化上文提到,webpack的模块是用id标志的,每个模块对就一个id,例如util对应2,但是这个id不是固定不变的,在n次修改和打包之后,util的id可能会变成了3,这个就比较坑了,给增量上线造成了阻力,即单独上一个html有风险。因为在common-chunk里面,util的id是上次打包的时候定的,但是你这次打包util的id变了,而你只想上home.html,在home.html里面引的home.js里面使用到的util的id对不上common-chunk里面的,导致不能在home里面正常地加载util这个模块。一个临时的解决办法是,home.js不要使用common-chunk,所有的模块都打包到home.js里面就不会有这个问题。
浙金院会计系会计133班最新文章
微信号:ZFC-k133扫描二维码关注公众号
Copyright2017.杨邱自媒体资讯站,让大家及时掌握各行各业第一手资讯新闻!

我要回帖

更多关于 微信更改绑定手机号 的文章

 

随机推荐