四、webpack较之其余相似工具备什么不一样?css
五、webpack为何要将全部资源放在一个文件里面?html
咱们知道,对于浏览器来讲,加载的资源越少,响应的速度也就越快,因此有时候咱们为了优化浏览器的性能,会尽量的将资源合并到一个主文件app.js里面。可是这致使的很大的缺点:vue
而webpack能够很好的解决以上缺点,由于它是一个十分聪明的模块打包系统,当你正确配置后,它会比你想象中的更强大,更优秀。node
一、生成package.json文件;jquery
如上经过一问一答的方式后会在根目录下生成package.json文件,以下所示:webpack
//详细的webpack.config.js结构分析: var path = require('path'); var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); var TransferWebpackPlugin = require('transfer-webpack-plugin'); module.exports = { devtool: 'source-map',//因为打包后的代码是合并之后的代码,不利于排错和定位,只须要在config中添加,这样出错之后就会采用source-map的形式直接显示你出错代码的位置。 //noParse:[/jquery/],//表示跳过jquery,不对其进行编译,这样能够提升打包的速度 //页面入口文件配置 entry: { page1: "./src/index.js", //page2: ["./src/index.js", "./src/main.js"],支持数组形式,将加载数组中的全部模块,但以最后一个模块做为输出 }, //入口文件输出配置 output: { path: "dist/js/page", filename: "[name].bundle.js",// page1.bundle.js 和 page2.bundle.js,并存放到 ./dist/js/page 文件夹下。 publicPath: "/dist/" //网站运行时的访问路径。 }, resolveLoader: { //指定默认的loader路径,不然依赖走到上游会找不到loader root: path.join(__dirname, 'node_modules'), alias: {//给本身写的loader设置别名 "seajs-loader": path.resolve( __dirname, "./web_modules/seajs-loader.js" ) } }, //新建一个开发服务器,而且当代码更新的时候自动刷新浏览器。 devServer: { historyApiFallback: true, noInfo: true, hot: true, inline: true, progress: true, port:9090 //端口你能够自定义 }, module: { // module.loaders 是最关键的一块配置。它告知 webpack每一种文件都须要使用什么加载器来处理: loaders: [ { test: /\.css$/, loader: 'style-loader!css-loader' },//.css 文件使用 style-loader 和 css-loader 来处理. //{ test: /\.css$/, loader: 'style!css' },其余写法一、"-loader"实际上是能够省略不写的,多个loader之间用“!”链接起来。 //{ test: /\.css$/, loaders: ["style", "css"] },其余写法二、用loaders数组形式; //.scss 文件使用 style-loader、css-loader 和 sass-loader 来编译处理。 //在chrome中咱们经过sourcemap能够直接调试less、sass源文件文件 { test: /\.scss$/, loader: 'style!css!sass?sourceMap'}, { test: /\.less$/, loader: 'style!css!less?sourceMap'},//.less 文件使用 style-loader、css-loader 和 less-loader 来编译处理 //.js 文件使用babel-loader来编译处理,设置exclude用来排除node_modules这个文件夹中的代码 { test: /\.js$/, loader: 'babel!jsx',exclude: /node_modules/ }, { test: /\.jsx$/, loader: "jsx-loader?harmony" },//.jsx 文件使用 jsx-loader 来编译处理 { test: /\.json$/,loader: 'json'}, //{ test: /\.(png|jpg|jpeg|gif)$/, loader: 'url-loader?limit=8192'}, //图片文件使用 url-loader 来处理,小于8kb的直接转为base64 {test: /\.(png|jpg|gif|svg)$/,loader: 'url', query: {limit: 10000,name: '[name].[ext]?[hash]'}//设置图片名称扩展名 }, { test: /\.jade$/, loader: "jade-loader" },//.jade 文件使用 jade-loader 来编译处理 { test: /\.ejs$/, loader: "ejs-loader" },//.ejs 文件使用 ejs-loader 来编译处理 { test: /\.handlebars$/, loader: "handlebars-loader" },//.handlebars 文件使用handlebars-loader来编译处理handlebars模板文件 { test: /\.dot$/, loader: "dot-loader" },//.dot 文件使用 dot-loader 来编译处理dot模板文件 { test: /\.vue$/, loader: "vue-loader" },//.vue 文件使用 vue-loader 来编译处理 { test: /\.coffee$/, loader: 'coffee-loader' },//.coffee 文件使用 coffee-loader 来编译处理 { test: /\.html$/,loader: 'vue-html'}, { test: /\.woff$/,loader: "url?limit=10000&minetype=application/font-woff"}, { test: /\.ttf$/,loader: "file"}, { test: /\.eot$/,loader: "file"}, { test: /\.svg$/,loader: "file"} ] }, //份内置插件和外置插件 plugins: [ //使用了一个 CommonsChunkPlugin 的插件,它用于提取多个入口文件的公共脚本部分,而后生成一个common.js来方便多页面之间进行复用。 new webpack.optimize.CommonsChunkPlugin('common.js'), new webpack.optimize.UglifyJsPlugin({//压缩文件 compressor: { warnings: false,//supresses warnings, usually from module minification }, except: ['$super', '$', 'exports', 'require'] //排除关键字(可选) }), new webpack.DefinePlugin({// definePlugin 接收字符串插入到代码当中, 因此你须要的话能够写上 JS 的字符串 __DEV__: JSON.stringify(JSON.parse(process.env.BUILD_DEV || 'true')), __PRERELEASE__: JSON.stringify(JSON.parse(process.env.BUILD_PRERELEASE || 'false')) }), new webpack.ProvidePlugin({//把一个全局变量插入到全部的代码中,支持jQuery plugin的使用;使用ProvidePlugin加载使用频率高的模块 //provide $, jQuery and window.jQuery to every script $: "jquery", jQuery: "jquery", "window.jQuery": "jquery" }), new webpack.NoErrorsPlugin(), //容许错误不打断程序 new TransferWebpackPlugin([ //把指定文件夹下的文件复制到指定的目录 {from: 'www'} ], path.resolve(__dirname,"src")), new HtmlwebpackPlugin({//用于生产符合要求的html文件; title: 'Hello World app', filename: 'assets/admin.html' }) ], //其它解决方案配置 resolve: { root: 'E:/github/flux-example/src', //绝对路径, 查找module的话从这里开始查找(可选) extensions: ['', '.js', '.html', '.css', '.scss'], //自动扩展文件后缀名,意味着咱们require模块能够省略不写后缀名 alias: { //模块别名定义,方便后续直接引用别名,无须多写长长的地址//后续直接 require('AppStore') 便可 AppStore : 'js/stores/AppStores.js', ActionType : 'js/actions/ActionType.js', AppAction : 'js/actions/AppAction.js' }, modulesDirectories: [//取相对路径,因此比起 root ,因此会多不少路径。查找module(可选) 'node_modules', 'bower_components', 'lib', 'src' ] } }; if (process.env.NODE_ENV === 'production') { module.exports.devtool = '#source-map' // http://vue-loader.vuejs.org/en/workflow/production.html module.exports.plugins = (module.exports.plugins || []).concat([ new webpack.DefinePlugin({ 'process.env': { NODE_ENV: '"production"' } }), new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false } }), //为组件分配ID,经过这个插件webpack能够分析和优先考虑使用最多的模块,并为它们分配最小的ID new webpack.optimize.OccurenceOrderPlugin() ]) }
plugins中包含不少的内置插件和外部插件,它们都有各自的功能,用来处理相关的文件,这里只是罗列了部分,具体用法请看webpack入门和实战(二):全面理解和运用plugins和loader。git
var webpack = require("webpack"); module.exports = { new webpack.optimize.UglifyJsPlugin({ compressor: { warnings: false, }, }) };
//npm install component-webpack-plugin 先要在安装该模版 var ComponentPlugin = require("component-webpack-plugin"); module.exports = { plugins: [ new ComponentPlugin() ] }
更多的插件以及插件的用法,你们能够到webpack的插件上查看。github
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>demo1</title> </head> <body> <div id="content"></div> <img src="./build/img/demo.png"> <script src="./build/js/index.js"></script> </body> </html>
index.js代码以下:web
require('./index.css');
index.css代码以下:正则表达式
#content{ width:121px; height:140px; background-color: red; }
效果以下:
RequireJS是一个工具库,主要用于客户端的模块管理。它可让客户端的代码分红一个个模块,实现异步或动态加载,从而提升代码的性能和可维护性。它的模块管理遵照 AMD规范(Asynchronous Module Definition)。RequireJS的基本思想是,经过define方法,将代码定义为模块;经过require方法,实现代码的模块加载。首先,将require.js嵌入网页,而后就能在网页中进行模块化编程了。<script data-main="scripts/main" src="scripts/require.js"></script>上面代码的data-main属性不可省略,用于指定主代码所在的脚本文件,在上例中为scripts子目录下的main.js文件。用户自定义的代码就放在这个main.js文件中。
SeaJS是一个遵循CMD规范的JavaScript模块加载框架,能够实现JavaScript的模块化开发及加载机制。
CommonJS API定义不少普通应用程序(主要指非浏览器的应用)使用的API,从而填补了这个空白。它的终极目标是提供一个相似Python,Ruby和Java标准库。这样的话,开发者可使用CommonJS API编写应用程序,而后这些应用能够运行在不一样的JavaScript解释器和不一样的主机环境中。在兼容CommonJS的系统中,你能够实用JavaScript程序开发:
- 服务器端JavaScript应用程序
- 命令行工具
- 图形界面应用程序
- 混合应用程序(如,Titanium或Adobe AIR)
还有很多⋯⋯这些规范的目的都是为了 JavaScript 的模块化开发,特别是在浏览器端的。目前这些规范的实现都能达成浏览器端模块化开发的目的。
二、AMD/CMD模式区别
2.1从官方推荐的写法上面得出:
CMD ----- 依赖就近
Js代码 //CMD define(function(require,exports,module){ var a = require('./a'); a.doSomthing(); });
AMD ----- 依赖前置
Js代码 //AMD define(['./a','./b'],function(a,b){ //...... a.doSomthing(); //...... b.doSomthing(); })
固然AMD也支持CMD的写法。
2.二、执行顺序上: