最开始只是想综合的初略学习下这几种技术,所以萌生了搭建一个简单的结构的想法;整个结构应该没有什么问题;已经放到了github
上,地址:webpack、sass、react、redux的简易demo入门
webpack
本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
我自己对webpack
的使用也不是很熟练,还没有很明白webpack
的设计思维,所以在配置的时候也是一脸懵逼,跟着官方文档和一些社区的文章来一步一步配置,主要还是需要知道这几个配置:
- 入口(entry)
- 输出(output)
- loader
- 插件(plugins)
- 解析(Resolve)
入口(entry)
起点或是应用程序的起点入口。从这个起点开始,应用程序启动执行。如果传递一个数组,那么数组的每一项都会执行。
entry
字段可以是string | [string] | object { <key>: string | [string] }
或者是函数【函数返回值是上面的三种类型中的一种】,本次demo
的选择是对象来处理,如下:
entry: { home: './src/scripts/pages/home/index.js' // homecss: './src/styles/pages/home.scss' // scss入口放到最开始的js中,webpack无法处理非js文件 },
输出(output)
output 位于对象最顶级键(key),包括了一组选项,指示 webpack 如何去输出、以及在哪里输出你的「bundle、asset 和其他你所打包或使用 webpack 载入的任何内容」。
通常而言,通过 output.filename 和 output.path 属性,来告诉 webpack bundle 的名称,以及我们想要生成(emit)到哪里。demo
中的配置如:
output: { path: path.join(__dirname + '/src/dist'),// publicPath:'/' // publicPath: path.join(__dirname + '/src/dist/'),// 加载外部资源,此选项指定在浏览器中所引用的「此输出目录对应的公开 URL」 filename: 'js/[name].js' }
需要注意的是,filename: 'js/[name].js'
这么写是因为webpack
支持入口文件为多个文件时可以配置不同的输出文件名,参考output-filename
loader
loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后你就可以利用 webpack 的打包能力,对它们进行处理。本质上,webpack loader 将所有类型的文件,转换为应用程序的依赖图可以直接引用的模块。
重要的是要记得,在 webpack 配置中定义 loader 时,要定义在 module.rules 中,而不是 rules。
module: { rules: [ { test: /\.js$/,exclude: /(node_modules|bower_components)/,use: { loader: 'babel-loader',options: { presets: ['@babel/preset-env','@babel/stage-3','@babel/react'] } } },{ test: /\.scss$/,use: extractSass.extract({ use: [{ loader: "css-loader" },{ loader: "sass-loader" }],// publicPath: './../',// 加载外部资源,把路径重新定义到dist目录下,而不是css里面 // use style-loader in development fallback: "style-loader" }) },{ test: /\.(png|svg|jpg|gif|jpeg)$/,use: [ { loader: 'file-loader',options: { name: '[name].[ext]',useRelativePath: true,// 图片相对路径 outputPath: 'images/' } } ] } ] }
以上是demo
的配置,在 webpack 的配置中 loader 有两个目标。
- 识别出应该被对应的 loader 进行转换的那些文件。(使用 test 属性)
- 转换这些文件,从而使其能够被添加到依赖图中(并且最终添加到 bundle 中)(use 属性)
可以看到,同一个文件可以顺序使用多个loader
来加载,每个loader
可以传递参数来进行特殊处理。
插件(plugins)
插件是 wepback 的支柱功能。webpack 自身也是构建于,你在 webpack 配置中用到的相同的插件系统之上!插件目的在于解决 loader 无法实现的其他事。
webpack 插件是一个具有 apply 属性的 JavaScript 对象。apply 属性会被 webpack compiler 调用,并且 compiler 对象可在整个编译生命周期访问。
由于插件可以携带参数/选项,你必须在 webpack
配置中,向 plugins
属性传入 new 实例。根据你的 webpack
用法,这里有多种方式使用插件。插件使用,插件列表
demo
中使用了两个plugins
,extract-text-webpack-plugin
& DefinePlugin
,都是按照官方插件文档配置的。
解析(Resolve)
这些选项能设置模块如何被解析。webpack 提供合理的默认值,但是还是可能会修改一些解析的细节。关于 resolver 具体如何工作的更多解释说明,请查看模块解析方式。
简单的说,就是会帮我们弄好一些默认的选项,比如别名alias
、extensions
模块默认后缀、mainFiles
默认文件入口等;
resolve: { mainFiles: ["index"],extensions: ['.js','.jsx'],alias: { 'stylepages': path.join(__dirname + '/src/styles/pages'),'scripts': path.join(__dirname + '/src/scripts/pages'),'commonjs': path.join(__dirname + '/src/scripts/common') } }
遇到问题
关于webpack无法把css文件作为入口,需要在js中引入css,然后进行css的分离
关于sass使用@import时来使用alias别名配置的路径时不被正确解析,sass-loader需要在使用别名的前面加上~
,stylelib
是别名,使用时@import '~stylelib/base.scss';
关于sass
和图片等外部资源的打包出现的路径不一致,,有以下几种方法:
- 第一种方法,可以在配置
fileloader
的时候使用相对路径:useRelativePath
{ test: /\.(png|svg|jpg|gif|jpeg)$/,use: [ { loader: 'file-loader',options: { name: '[name].[ext]',// 图片相对路径 outputPath: 'images/' } } ] }
- 第二种方法,在使用
ExtractTextWebpackPlugin
的时候,可以根据已有的loader来重新提取loader
,在提取新的loader
时,可以配置公共路径publicPath
const ExtractTextPlugin = require("extract-text-webpack-plugin"); const extractSass = new ExtractTextPlugin({ filename: "css/[name].css",disable: process.env.NODE_ENV === "development" }); // loader 里面 { test: /\.scss$/,use: extractSass.extract({ use: [{ loader: "css-loader" },{ loader: "sass-loader" }],publicPath: './../',// 把路径重新定义到dist目录下,而不是css里面 // use style-loader in development fallback: "style-loader" }) }
- 第三种方法,直接在所有的输出目录处使用当前的打包路径,
publicPath
output: { path: path.join(__dirname + '/src/dist'),publicPath:'./' // publicPath: path.join(__dirname + '/src/dist/'),// 加载外部资源,此选项指定在浏览器中所引用的「此输出目录对应的公开 URL」 filename: 'js/[name].js' }
sass
Sass 是一款强化 CSS 的辅助工具,它在 CSS 语法的基础上增加了变量 (variables)、嵌套 (nested rules)、混合 (mixins)、导入 (inline imports) 等高级功能,这些拓展令 CSS 更加强大与优雅。使用 Sass 以及 Sass 的样式库(如 Compass)有助于更好地组织管理样式文件,以及更高效地开发项目。
使用sass可以感受到以下几点的优势:
- 合理的嵌套规则,不需要重复书写selector。
- 变量$、占位符%都可以很好的提供复用性
- 函数、运算可以很好的增加灵活性
这里就不多说sass的学习了,可以查看sass中文、sass官网
react
React 是一个采用声明式,高效而且灵活的用来构建用户界面的框架。
学习react的重要内容包括:
- jsx的书写语法
- 组件Components【props、state、Lifecycle...】
- 虚拟dom,
- 组件渲染和diff,Lists and Keys
更多的学习react学习官网
redux
Redux 是 JavaScript 状态容器,提供可预测化的状态管理。应用中所有的 state 都以一个对象树的形式储存在一个单一的 store 中。 惟一改变 state 的办法是触发 action,一个描述发生什么的对象。 为了描述 action 如何改变 state 树,你需要编写 reducers;
- 应用中所有的 state 都以一个对象树的形式储存在一个单一的 store 中,初始时由reducer初识态来创建
- 改变state的唯一方法就是触发dispatch一个action,
- 一个action是本质上一个对象,用来把最新的数据传到store的有效载荷
- Reducer就是把action这个有效载荷解析,并应用到store之中;
具体实践中:
- 书写reducer,来确定初始时的state
- 根据初始reducer来创建store,并使用store.subscribe来监听store变化时的操作
- 书写action,来承载每次修改store的变化
- 在交互等情况使用dispatch一个相应的action,
- reducer来响应action,并更新store,[store.subscribe监听函数将会被执行来驱动页面变化]
import { createStore } from 'redux'; /** * 这是一个 reducer,形式为 (state,action) => state 的纯函数。 * 描述了 action 如何把 state 转变成下一个 state。 * * state 的形式取决于你,可以是基本类型、数组、对象、 * 甚至是 Immutable.js 生成的数据结构。惟一的要点是 * 当 state 变化时需要返回全新的对象,而不是修改传入的参数。 * * 下面例子使用 `switch` 语句和字符串来做判断,但你可以写帮助类(helper) * 根据不同的约定(如方法映射)来判断,只要适用你的项目即可。 */ function counter(state = 0,action) { switch (action.type) { case 'INCREMENT': return state + 1; case 'DECREMENT': return state - 1; default: return state; } } // 创建 Redux store 来存放应用的状态。 // API 是 { subscribe,dispatch,getState }。 let store = createStore(counter); // 可以手动订阅更新,也可以事件绑定到视图层。 store.subscribe(() => console.log(store.getState()) ); // 改变内部 state 惟一方法是 dispatch 一个 action。 // action 可以被序列化,用日记记录和储存下来,后期还可以以回放的方式执行 store.dispatch({ type: 'INCREMENT' }); // 1 store.dispatch({ type: 'INCREMENT' }); // 2 store.dispatch({ type: 'DECREMENT' }); // 1
异步redux
像 redux-thunk 或 redux-promise 这样支持异步的 middleware 都包装了 store 的 dispatch() 方法,以此来让你 dispatch 一些除了 action 以外的其他内容,例如:函数或者 Promise。
redux-react
Redux 官方提供的 React 绑定库。 具有高效且灵活的特性。
结合react来完善了下redux的使用,不需要我们每次都使用store.subscribe
来监听store的变化,提供了新的接口:
<Provider store> 可以在最顶层将store传递至每个需要store的子组件 connect([mapStateToProps],[mapDispatchToProps],[mergeProps],[options]) 可以将一些state映射到某个组件,来驱动组件渲染
总结
react-redux-demo
需要webpack3以上
运行方式:
`npm install` 安装相关依赖 `webpack` 执行webpack来进行打包
在浏览器中打开目录下的/html/pages/home.html
文件即可访问结果
➜ react-redux-demo git:(master) tree -I node_modules . ├── html │ └── pages │ └── home.html ├── package-lock.json ├── package.json ├── readMe.md ├── src │ ├── dist │ │ ├── css │ │ │ └── home.css │ │ ├── images │ │ │ └── head.jpeg │ │ └── js │ │ └── home.js │ ├── scripts │ │ ├── common │ │ └── pages │ │ └── home │ │ ├── actions │ │ │ ├── data.js │ │ │ └── index.js │ │ ├── components │ │ │ ├── app.js │ │ │ ├── article │ │ │ │ └── index.js │ │ │ └── consults │ │ │ └── index.js │ │ ├── index.js │ │ ├── reducers │ │ │ ├── data.js │ │ │ └── index.js │ │ └── store │ │ └── index.js │ └── styles │ ├── images │ │ └── home │ │ └── head.jpeg │ ├── lib │ │ └── base.scss │ ├── module │ └── pages │ └── home.scss └── webpack.config.js
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。