为了账号安全,请及时绑定邮箱和手机立即绑定

请问该如何用 webpack fetch 异步引用 json?

/ 猿问

请问该如何用 webpack fetch 异步引用 json?

慕运维1137616 2019-07-17 15:11:21

如何用 webpack fetch 异步引用 json


查看完整描述

4 回答

?
喵喵时光机

参考github上面的示例:
https://github.com/newtriks/generator-react-webpack

'use strict';
let opts = require('./configopts.json');

/**
* Get a setting
* @param {String} setting
* @return {Mixed} setting or null if not found
*/
let getSetting = (setting) => {
return opts[setting] !== undefined ? opts[setting] : null;
}

/**
* Get choices for a given setting
* @param {String} setting
* @return {Mixed} Result or null if nothing was found
*/
let getChoices = function getChoices(setting) {

let config = getSetting(setting);
return config && Array.isArray(config.options) ? config.options : null;
}

/**
* Get the wanted choice by key
* @param {String} setting
* @param {String} key
* @return {Object}
*/
let getChoiceByKey = (setting, key) => {

let choices = getChoices(setting);
if(!choices) {
return null;
}

let result = null;

for(let choice of choices) {

if(choice.name === key) {
result = choice;
break;
}
}

return result;
}

/**
* Get the default choice for a config setting
* @param {String} setting
* @return {Mixed}
*/
let getDefaultChoice = (setting) => {
let config = getSetting(setting);
return config && config.default !== undefined && config.default.length > 0 ? config.default : null;
}

// getChoices
// getDefault

module.exports = {
getSetting: getSetting,
getChoices: getChoices,
getChoiceByKey: getChoiceByKey,
getDefaultChoice: getDefaultChoice
};



查看完整回答
反对 回复 2019-07-28
?
慕侠2389804

他像 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
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
}
};

这仅仅是 JavaScript, 可以随意添加要运行的代码.
3. 怎样启动 webpack
切换到有 webpack.config.js 的目录然后运行:
webpack 来执行一次开发的编译
webpack -p for building once for production (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
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
module: {
loaders: [
{ test: /\.coffee$/, loader: 'coffee-loader' },
{ test: /\.js$/, loader: 'jsx-loader?harmony' } // loaders 可以接受 querystring 格式的参数
]
}
};

要开启后缀名的自动补全, 你需要设置 resolve.extensions 参数指明那些文件 Webpack 是要搜索的:
// webpack.config.js
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
module: {
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
module.exports = {
entry: './main.js',
output: {
path: './build', // 图片和 JS 会到这里来
publicPath: 'http://mycdn.com/', // 这个用来成成比如图片的 URL
filename: 'bundle.js'
},
module: {
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'))
});

module.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 module":
// webpack.config.js
module.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');

module.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/" // 引用你的文件时考虑使用的地址



查看完整回答
反对 回复 2019-07-28
?
烙印99

第一步:
mkdir react-demo
cd react-demo
npm init -y
npm i webpack webpack-dev-server html-webpack-plugin webpack-merge babel-loader babel-core css-loader style-loader babel-preset-react-hmre babel-preset-es2015 babel-preset-react -D
mkdir app
mkdir dist
mkdir assets
touch assets/index.tmpl.html

第二步,编辑index.tmpl.html为如下:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<div id="root"></div>
</body>
</html>

第二步,打开你的 package.json 文件,添加如下字符串:
...
"scripts": {
"build": "webpack",
"start": "webpack-dev-server"
},
"babel":{
"presets": [
"es2015",
"react"
],
"env": {
"start": {
"presets": [
"react-hmre"
]
}
}
}
...

第三步:在根目录新建一个 webpack.config.js 的文件,写入如下配置
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const merge = require('webpack-merge');
const TARGET = process.env.npm_lifecycle_event;
process.env.BABEL_ENV = TARGET;
const PATHS = {
app: path.join(__dirname, 'app'),
build: path.join(__dirname, 'dist'),
template: path.resolve(__dirname, 'assets', 'index.tmpl.html'),
};
const common = {
entry: {
app: PATHS.app,
},
output: {
path: PATHS.build,
filename: 'bundle.js',
},
plugins: [
new HtmlWebpackPlugin({
title: 'react demo',
template: PATHS.template,
inject: 'body',
}),
],
module: {
loaders: [{
test: /\.jsx?$/,
loaders: ['babel?cacheDirectory'],
include: PATHS.app,
}, {
test: /\.css$/,
loaders: ['style', 'css'],
include: PATHS.app,
}],
},
resolve: {
extensions: ['', '.js', '.jsx'],
},
};
if (TARGET === 'start' || !TARGET) {
module.exports = merge(common, {
devtool: 'eval-source-map',
devServer: {
contentBase: '/dist',
historyApiFallback: true,
hot: true,
inline: true,
progress: true,
stats: 'errors-only',
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
],

});
}
if (TARGET === 'build') {
module.exports = merge(common, {});
}

第四步:到这里,关于react的需要的webpack方面的配置就结束了,接下来我们来写一个很小的示例来生成一个真正的react文件。
npm i react react-dom react-router -S
touch app/App.jsx
touch app/index.jsx

编辑 App.jsx 文件如下:
import React, { Component } from 'react';
import {
Router,
Route,
Link,
IndexLink,
IndexRoute,
hashHistory,
} from 'react-router';

const activeStyle = {
color: '#53acff',
};
const Nav = () => (
<div>
<IndexLink onlyActiveOnIndex activeStyle={activeStyle} to="/">主页</IndexLink>

<IndexLink onlyActiveOnIndex activeStyle={activeStyle} to="/address">地址</IndexLink>

</div>
);

const Container = (props) => <div>
<Nav /> { props.children }
</div>;

const Twitter = () => <div>@xiaomingplus twitter</div>;
const Instagram = () => <div>@xiaomingplus instagram</div>;

const NotFound = () => (
<h1>404.. 找不到该页面!</h1>
);
const Home = () => <h1>你好,这是主页。</h1>;
const Address = (props) => <div>
<br />
<Link activeStyle={{ color: '#53acff' }} to="/address">这是Twitter</Link>
<Link to="/address/instagram">这是Instagram</Link>
<h1>欢迎互关!</h1>
{ props.children }
</div>;

class App extends Component {
construct() {
}
render() {
return (
<Router history={hashHistory}>
<Route path="/" component={Container}>
<IndexRoute component={Home} />
<Route path="/address" component={Address}>
<IndexRoute component={Twitter} />
<Route path="instagram" component={Instagram} />
</Route>
<Route path="*" component={NotFound} />
</Route>
</Router>
);
}
}

export default App;

编辑 index.jsx 文件:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.jsx';

ReactDOM.render(
<App />, document.getElementById('root'));

ok,到这里你已经实用react-router构建了一个有路由的应用,接下来启动这个应用吧。
npm start

用浏览器访问: http://localhost:8080 ,你将看到如下界面



查看完整回答
反对 回复 2019-07-28
?
狐的传说


向左转|向右转


这种配置方式和你的可能有点不同,仅作参考

dev.config.js部分

var path = require('path');

var webpack = require('webpack');

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

var autoprefixer = require('autoprefixer');

var csswring = require('csswring');


module.exports = {

  devtool: 'cheap-module-eval-source-map',

  entry: [

    'webpack-hot-middleware/client',

    './src/index',

  ],


  output: {

    filename: 'bundle.js',

    path: path.join(__dirname, '/dist/'),

    publicPath: '/dist/',

  },


  plugins: [

    new webpack.DefinePlugin({

      __DEVELOPMENT__: true

    }),

    new ExtractTextPlugin('bundle.css'),

    new webpack.optimize.OccurenceOrderPlugin(),

    new webpack.HotModuleReplacementPlugin(),

    new webpack.NoErrorsPlugin(),

    new webpack.ProvidePlugin({

      jQuery: 'jquery',

    }),

  ],


  resolve: {

    extensions: ['', '.jsx', '.js', '.json'],

    modulesDirectories: ['node_modules', 'src'],

  },


  module: {

    loaders: [{

      test: /bootstrap\/js\//,

      loader: 'imports?jQuery=jquery',

    }, {

      test: /\.woff(\?v=\d+\.\d+\.\d+)?$/,

      loader: 'url?limit=10000&mimetype=application/font-woff',

    }, {

      test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/,

      loader: 'url?limit=10000&mimetype=application/font-woff2',

    }, {

      test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,

      loader: 'url?limit=10000&mimetype=application/octet-stream',

    }, {

      test: /\.otf(\?v=\d+\.\d+\.\d+)?$/,

      loader: 'url?limit=10000&mimetype=application/font-otf',

    }, {

      test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,

      loader: 'file',

    }, {

      test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,

      loader: 'url?limit=10000&mimetype=image/svg+xml',

    }, {

      test: /\.js$/,

      loaders: ['react-hot', 'babel?stage=0&loose[]=es6.modules'],

      exclude: /node_modules/,

    }, {

      test: /\.scss$/,

      loader: 'css?localIdentName=[path]!postcss-loader!sass',

    }, {

      test: /\.png$/,

      loader: 'file?name=[name].[ext]',

    }, {

      test: /\.jpg$/,

      loader: 'file?name=[name].[ext]',

    }],

  },

  postcss: function() {

    return [autoprefixer({ browsers: ['last 2 versions', 'safari 5', 'ie 9', 'ios 6', 'android 4'] }), csswring];

  },

};


prod.config,js部分

var path = require('path');

var webpack = require('webpack');

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

var autoprefixer = require('autoprefixer');

var csswring = require('csswring');


module.exports = {

  devtool: 'source-map',

  entry: [

    './src/index',

  ],


  output: {

    filename: 'bundle.js',

    path: path.join(__dirname, '../dist/'),

    publicPath: 'dist/',

  },


  plugins: [

    new webpack.DefinePlugin({

      'process.env': {

        NODE_ENV: '"production"',

      },

      __DEVELOPMENT__: false,

    }),

    new ExtractTextPlugin('bundle.css'),

    new webpack.optimize.DedupePlugin(),

    new webpack.optimize.OccurenceOrderPlugin(),

    new webpack.optimize.UglifyJsPlugin({

      compress: {

        warnings: false,

      },

    }),

    new webpack.ProvidePlugin({

      jQuery: 'jquery',

    }),

  ],


  resolve: {

    extensions: ['', '.jsx', '.js', '.json'],

    modulesDirectories: ['node_modules', 'src'],

  },


  module: {

    loaders: [{

      test: /bootstrap\/js\//,

      loader: 'imports?jQuery=jquery',

    }, {

      test: /\.woff(\?v=\d+\.\d+\.\d+)?$/,

      loader: 'url?limit=10000&mimetype=application/font-woff',

    }, {

      test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/,

      loader: 'url?limit=10000&mimetype=application/font-woff2',

    }, {

      test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,

      loader: 'url?limit=10000&mimetype=application/octet-stream',

    }, {

      test: /\.otf(\?v=\d+\.\d+\.\d+)?$/,

      loader: 'url?limit=10000&mimetype=application/font-otf',

    }, {

      test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,

      loader: 'file',

    }, {

      test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,

      loader: 'url?limit=10000&mimetype=image/svg+xml',

    }, {

      test: /\.js$/,

      loaders: ['react-hot', 'babel?stage=0&loose[]=es6.modules'],

      exclude: /node_modules/,

    }, {

      test: /\.scss$/,

      loader: 'css!postcss-loader!sass',

    }, {

      test: /\.png$/,

      loader: 'file?name=[name].[ext]',

    }, {

      test: /\.jpg$/,

      loader: 'file?name=[name].[ext]',

    }],

  },

  postcss: function() {

    return [autoprefixer({ browsers: ['last 2 versions', 'safari 5', 'ie 9', 'ios 6', 'android 4'] }), csswring];

  },

};



查看完整回答
反对 回复 2019-07-28

添加回答

回复

举报

0/150
提交
取消
意见反馈 邀请有奖 帮助中心 APP下载
官方微信