how to upgrade webpack from 3 to 5 - node.js

I really need someone's help.
In this repo,
https://github.com/ueno-llc/starter-kit-universally.git
I don't know how to upgrade the webpack.
The error is from new webpack.NamedChunksPlugin, new webpack.optimize.CommonsChunkPlugin
I can't fix it by myself...
Can anyone help me for this issue ?
import fs from 'fs';
import _isArray from 'lodash/isArray';
import _get from 'lodash/get';
import appRootDir from 'app-root-dir';
import path from 'path';
import webpack from 'webpack';
import ExtractCssChunks from 'extract-css-chunks-webpack-plugin';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import ChunkManifestWebpackPlugin from 'chunk-manifest-webpack-plugin';
import NameAllModulesPlugin from 'name-all-modules-plugin';
import config from '../';
import { removeNil } from '../../internal/utils/arrays';
import { ifElse } from '../../internal/utils/logic';
function externals() {
// UENO: Define externals
// We don't want our node_modules to be bundled with any bundle that is
// targetting the node environment, prefering them to be resolved via
// native node module system.
// Some of our node_modules may contain files that depend on our
// webpack loaders, e.g. CSS or SASS.
// For these cases please make sure that the file extensions are
// registered within the following configuration setting.
const whitelist = [
/\.bin/,
'source-map-support/register',
'react-universal-component',
'webpack-flush-chunks',
]
// And any items that have been whitelisted in the config need
// to be included in the bundling process too.
.concat(config('nodeExternalsFileTypeWhitelist') || []);
return fs
.readdirSync(path.resolve(appRootDir.get(), 'node_modules'))
.filter(x => !whitelist.some((w) => {
if (w instanceof RegExp) {
return w.test(x);
}
return x === w;
}))
.reduce((ext, mod) => {
// mark this module as external
// https://webpack.js.org/configuration/externals
ext[mod] = `commonjs ${mod}`;
return ext;
}, {});
}
export default (webpackConfig, buildOptions) => {
const { target, optimize = false, localIdentName } = buildOptions;
const isProd = optimize;
const isDev = !isProd;
const isClient = target === 'client';
const isNode = !isClient;
const ifNode = ifElse(isNode);
const ifClient = ifElse(isClient);
const ifProdClient = ifElse(isProd && isClient);
// Overwrite the externals because apparently `webpack-node-externals` does not
// work well with `webpack-flush-chunks`
if (isNode) {
webpackConfig.externals = [externals()];
}
// Remove ExtractTextPlugin
const etpIndex = webpackConfig.plugins.findIndex(p => p instanceof ExtractTextPlugin);
if (etpIndex > -1) {
webpackConfig.plugins.splice(etpIndex, 1);
}
// Add some plugins for css code splitting
webpackConfig.plugins.push(
...removeNil([
// NamedModulesPlugin, NamedChunksPlugin and NameAllModulesPlugin (see below) are all here to
// deal with chunk hashes.
// See https://medium.com/webpack/predictable-long-term-caching-with-webpack-d3eee1d3fa31
ifClient(new webpack.NamedModulesPlugin()),
ifClient(
new webpack.NamedChunksPlugin((chunk) => {
if (chunk.name) {
return chunk.name;
}
return chunk.mapModules(m => path.relative(m.context, m.request)).join('_');
}),
),
ifClient(new ExtractCssChunks({
filename: isDev ? '[name].js' : '[name]-[contenthash].css',
})),
ifProdClient(new ChunkManifestWebpackPlugin({
filename: '../manifest.json',
manifestVariable: '__WEBPACK_MANIFEST__',
})),
// To make sure chunk hashes stay the same if their contents don’t change
// see: https://webpack.js.org/guides/caching/#module-identifiers
ifClient(new webpack.HashedModuleIdsPlugin()),
// Add vendor code chunk
ifProdClient(
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
filename: '[name]-[chunkhash].js',
// Put all node_modules into one chunk
// see: https://webpack.js.org/plugins/commons-chunk-plugin/#passing-the-minchunks-property-a-function
minChunks: module => module.context && module.context.includes('node_modules'),
}),
),
// Add webpack boilerplate chunk
ifClient(
new webpack.optimize.CommonsChunkPlugin({
name: 'bootstrap', // needed to put webpack bootstrap code before chunks
filename: isDev ? '[name].js' : '[name]-[chunkhash].js',
}),
),
ifClient(new NameAllModulesPlugin()),
// We only want one server chunk
ifNode(
new webpack.optimize.LimitChunkCountPlugin({
maxChunks: 1,
}),
),
]),
);
const { rules } = webpackConfig.module;
const moduleRules = [..._get(rules, '0.oneOf', rules)];
// Overwrite css loader ExtractTextPlugin
const cssRule = moduleRules.find(r => r.test.test('.css'));
if (cssRule && _isArray(cssRule.use)) {
// Find plugin
const pluginIndex = cssRule.use.findIndex(u =>
Object.prototype.hasOwnProperty.call(u, 'loader') && /extract-text-webpack-plugin/.test(u.loader));
if (pluginIndex > -1) {
const loaders = ExtractCssChunks.extract({
fallback: 'style-loader',
use: [
`css-loader?modules=1&importLoaders=1&localIdentName=${localIdentName}`,
'postcss-loader',
'sass-loader?outputStyle=expanded',
],
});
cssRule.use.splice(
pluginIndex,
loaders.length,
...loaders,
);
}
}
// Overwrite node_modules css loader ExtractTextPlugin
const nmCssRule = moduleRules.find(r =>
r.test.test('node_modules.css') &&
(!r.exclude || !r.exclude.test('node_modules.css')));
if (nmCssRule && _isArray(nmCssRule.use)) {
// Find plugin
const pluginIndex = nmCssRule.use.findIndex(u =>
Object.prototype.hasOwnProperty.call(u, 'loader') && /extract-text-webpack-plugin/.test(u.loader));
if (pluginIndex > -1) {
const loaders = ExtractCssChunks.extract({
fallback: 'style-loader',
use: ['css-loader', 'postcss-loader'],
});
nmCssRule.use.splice(
pluginIndex,
loaders.length,
...loaders,
);
}
}
return webpackConfig;
};
===
I have tried to use webpack.config.js, but still failed...
Please help me :(

Related

How to set env.development and env.production in Preact app

On react app, you can create .env.production and .env.development and enter different key and values like this.
REACT_APP_API_URL= "xyz"
to pick environment variables automatically based on commands used --> npm start or npm run build.
What is the equivalent process in preact?
It is my solution
env.js in the root of project:
import fs from 'fs';
import dotenv from 'dotenv';
function getAppEnvironment() {
const prefix = "PREACT";
return Object.keys(process.env)
.filter((key) => new RegExp(`^${prefix}_`, 'i').test(key))
.reduce((env, key) => {
env[key] = process.env[key];
return env;
}, {});
}
function resolveFile(file) {
const path = fs.realpathSync(process.cwd());
return `${path}/${file}`;
}
function getEnvFiles(production) {
const key = production ? 'production' : 'development';
return [
resolveFile(".env"),
resolveFile(".env.local"),
resolveFile(`.env.${key}`),
resolveFile(`.env.${key}.local`),
].filter(Boolean);
}
export function getEnvironment(production) {
const dotenvFiles = getEnvFiles(production);
dotenvFiles.forEach((dotenvFile) => {
if (fs.existsSync(dotenvFile)) {
dotenv.config({
path: dotenvFile,
override: true
})
}
});
return getAppEnvironment();
}
export default getEnvironment;
then create or modify your preact.config.js:
import getEnvironment from './env';
export default {
plugins: [],
webpack(config, env, helpers) {
config.plugins.push(
new helpers.webpack.DefinePlugin({
'process.env': JSON.stringify(getEnvironment(env.production))
}),
);
},
};

copying files using `ncp` throws: no such file or directory, mkdir

I'm using ncp to copy files as following:
import ncp from "ncp";
import { promisify } from "util";
const ncpPromise = promisify(ncp);
const copyAssets = async (exportFolderName, includeSourceMaps) => {
const assets = glob.sync("**/", { cwd: distPath });
const options = { clobber: true, stopOnErr: true };
if (!includeSourceMaps) {
options.filter = (f) => {
return !f.endsWith(".map");
};
}
return Promise.all(
assets.map((asset) => {
return ncpPromise(
path.join(distPath, asset),
path.join(exportPath, exportFolderName, asset),
options
);
})
);
};
But this sometimes fails with the following error:
"ENOENT: no such file or directory, mkdir '/path/to/folder'"
How can I solve this ?
I guess you are trying to copy all files matching for the given glob, so you need to do:
const assets = glob.sync("**/*.*", { cwd: distPath }); // note the *.*
For example, your current glob in question will result into:
[
'folder1/',
'folder2/',
]
whereas the glob in this answer will result into (This is what you want):
[
'folder1/file1.txt',
'folder1/file2.txt',
'folder2/anotherfile.txt',
]
An Alternative:
Seems like ncp isn't being maintained. So, you can use fs-extra, it can copy file and directory as well:
const glob = require("glob");
const path = require("path");
const fs = require("fs-extra");
const copyAssets = async (exportFolderName, includeSourceMaps) => {
const assets = glob.sync("**/*.*", { cwd: distPath });
const options = { overwrite: true };
if (!includeSourceMaps) {
options.filter = (f) => {
return !f.endsWith(".map");
};
}
return Promise.all(
assets.map((asset) => {
return fs
.copy(
path.join(distPath, asset),
path.join(exportPath, exportFolderName, asset),
options
)
.catch((e) => console.log(e));
})
);
};
NPM qir (yes, it is published by myself) is another choice:
const qir = require('qir');
qir.asyncing.copy('/A/path/to/src', '/B/path/to/dest')
.then(() => { /* OK */ }
.catch(ex => { /* Something wrong */ }
;
Here, /A/path/to/src may be a file or a folder, and /B/path/to is not required to exist already.
There is a synchronous way:
const qir = require('qir');
qir.syncing.copy('/A/path/to/src', '/B/path/to/dest');
And, if both src and dest located in the same directory:
const qir = require('qir');
let q = new qir.AsyncDir('/current/working/dir');
q.copy('A/path/to/src', 'B/path/to/dest')
.then(() => { /* OK */ }
.catch(ex => { /* Something wrong */ }
;
It will copy /current/working/dir/A/path/to/src to /current/working/dir/B/path/to/dest.

Loading files from all directories inside specific directory

Good time of the day,
I've been trying to add 'modularity' to my application by splitting the Vuex store into many different locations.
So far, i'm totally fine with loading 'local' modules (inside the store folder) with the following piece of code:
const localRequireContext = require.context('./modules', false, /.*\.js$/);
const localModules = localRequireContext.keys().map((file) => [file.replace(/(^.\/)|(\.js$)/g, ''), localRequireContext(file)]).reduce((localModules, [name, module]) => {
if (module.namespaced === undefined) {
module.namespaced = true;
}
return { ...localModules, [name]: module };
}, {});
const createStore = () => {
return new Vuex.Store({
modules: localModules
})
};
export default createStore;
However, what i'm trying to achieve seems to be rather impossible for me (i'm not new to the web app development, but actually never had a chance to play around with 'core' libraries of Node.js, Webpack, etc).
I have the following structure
root
|-assets
|-components
|-config
|-lang
|-layouts
|-libs
|-middleware
|-modules
|----company
|--------module
|-----------store
|--------------index.js (module index)
|-pages
|-plugins
|-store
|----index.js (main index)
So what i'm trying to achieve, is to get to the ~/modules folder, go inside each of company directory (namespace for module), open the module directory (the name of the module), navigate to the store folder and import index.js file, with roughly the following content:
import module from '../config/module';
export const namespace = [module.namespace, module.name].join('/');
export const state = () => ({
quotes: null,
team: null,
articles: null
});
export const getters = {
quotes: (state) => state.quotes,
team: (state) => state.team,
articles: (state) => state.articles
};
As i've already said, i'm not much of a 'guru' when it comes to these complicated (for me) things, so any help is really appreciated!
So far, i went the 'dumb road' and just tried to use the following:
const modulesRequireContext = require.context('../modules/**/**/store', false, /.*\.js$/);
But, no luck it is - Cannot find module 'undefined'
The final file (in my mind) should look something like this:
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const localRequireContext = require.context('./modules', false, /.*\.js$/);
const localModules = localRequireContext.keys().map((file) => [file.replace(/(^.\/)|(\.js$)/g, ''), localRequireContext(file)]).reduce((localModules, [name, module]) => {
if (module.namespaced === undefined) {
module.namespaced = true;
}
return { ...localModules, [name]: module };
}, {});
const modulesRequireContext = require.context('CORRECT_WAY_OF_SEARCHING_IN_SUB_DIRECTORIES', false, /.*\.js$/);
const addedModules = modulesRequireContext.keys().map((file) => [file.replace(/(^.\/)|(\.js$)/g, ''), modulesRequireContext(file)]).reduce((addedModules, [name, module]) => {
return { ...addedModules, [module.namespace]: module };
}, {});
let modules = { ...localModules, ...addedModules };
const createStore = () => {
return new Vuex.Store({
modules: modules
})
};
export default createStore;

Hot Module Reloading is making initial page request take 10-20s, with Webpack, Koa, Vue.js

For some reason most page refreshes re-request the bundle.js file and it takes about 10-15-20 seconds to download from localhost. This all from localhost, and the bundle.js file is about 1mb in size. The request for this file only seems to crawl, loading a few kilobytes at a time.
Some observations:
After some digging it seems to be stalling out on the initial call to the server from __webpack_hmr, but I'm not sure as this call happens after the call to bundle.js. Below is the log of the server request flow.
It is only slow on pages that have more than one or two components, ie. anything other than the homepage. This alludes to the idea that it might be related to the hot module reloading.
The homepage will still take > 5s (sometimes 10-20) just like the other pages, but if I refresh the page with Ctrl+R, it comes back nearly instantly. If I do an address-bar refresh, it takes longer. The other pages still take just as long no matter if I Ctrl+R or do an address-bar reload...
Update: I removed the hot module replacement, and it definitely seems to be the source of the issue, as the pages load instantly without it.
Request log:
-- Response time GET / = 609ms
--> GET / 200 647ms 2.55kb
<-- GET /main.aafc9fb7f6a0c7f127edb04734d29547.css
--> GET /main.aafc9fb7f6a0c7f127edb04734d29547.css 200 17ms 3.43kb
<-- /bundle.js
--> GET /bundle.js 200 18ms 1.29mb
<-- GET /__webpack_hmr
And then in the chrome console, for this request it shows:
Here's my setup:
Using Koa as the server environment (using streaming/chunking in initial response)
Using webpack with hot module reloading
Using Vue.js as a frontend framework, with server-side rendering
bundle.js is served through the typical serve-static package
bundle.js doesn't seem to be being cached at all. Why is this?
On the Koa side of things, I started with some boilerplate package to do all this server-side rendering and such. This has been happening since I started messing around with this setup, and webpack in general, so I'm trying to get to the bottom of it. It seems to be a little random, where sometimes it will come back in < 1s, but most times it takes 10+ seconds. Sometimes 30+ seconds?!
I've also tried to use different libraries to serve the static files, but they all seem to do this.
Here is my main webpack config ('webpack.client', extended below):
'use strict'
const path = require('path')
const webpack = require('webpack')
const AssetsPlugin = require('assets-webpack-plugin')
const assetsPluginInstance = new AssetsPlugin({path: path.join(process.cwd(), 'build')})
const postcss = [
require('precss')()
//require('autoprefixer')({browsers: ['last 2 versions']}),
]
module.exports = {
entry: [
'./src/client-entry.js'
],
output: {
path: path.join(process.cwd(), 'build'),
filename: 'bundle.js',
publicPath: '/'
},
resolve: {
extensions: ['', '.vue', '.js', '.json']
},
module: {
loaders: [
{
test: /\.vue$/,
loaders: ['vue']
},
{
test: /\.js$/,
loaders: ['babel'],
exclude: [/node_modules/]
},
{
test: /\.json$/,
loaders: ['json'],
exclude: [/node_modules/]
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'url?limit=10000&name=images/[hash].[ext]',
include: path.src,
},
{
test: /\.woff($|\?)|\.woff2($|\?)|\.ttf($|\?)|\.eot($|\?)|\.svg($|\?)/,
loader: 'url-loader',
include: path.src,
}
]
},
node: { net: 'empty', dns: 'empty' },
postcss,
vue: {
postcss,
loaders: {}
},
plugins: [
assetsPluginInstance
]
}
And also this (extends the previous):
'use strict'
const webpack = require('webpack')
const config = require('./webpack.client')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
config.entry.push('webpack-hot-middleware/client')
//config.devtool = 'inline-eval-cheap-source-map'
config.plugins = config.plugins.concat([
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new webpack.DefinePlugin({
'__DEV__': true,
'process.env.NODE_ENV': JSON.stringify('development')
}),
new ExtractTextPlugin('[name].[contenthash].css')
])
config.vue.loaders = {
postcss: ExtractTextPlugin.extract(
'vue-style-loader',
'css-loader?sourceMap'
),
css: ExtractTextPlugin.extract(
'vue-style-loader',
'css-loader?sourceMap'
)
}
module.exports = config
Here is my server index.js file for Koa:
import path from 'path'
import fs from 'fs'
import Koa from 'koa'
import convert from 'koa-convert'
//import serve from 'koa-static-server'
import serveStatic from 'koa-static'
import {PassThrough} from 'stream'
import {createBundleRenderer} from 'vue-server-renderer'
import serialize from 'serialize-javascript'
import MFS from 'memory-fs'
import assets from '../build/webpack-assets'
import cookie from 'koa-cookie'
let renderer
const createRenderer = fs => {
const bundlePath = path.resolve(process.cwd(), 'build/server-bundle.js')
return createBundleRenderer(fs.readFileSync(bundlePath, 'utf-8'))
}
const app = new Koa();
app.use(cookie());
if (process.env.NODE_ENV === 'development') {
// DEVELOPMENT, with hot reload
const webpack = require('webpack')
const webpackConfig = require('../config/webpack.client.dev')
const compiler = webpack(webpackConfig)
const devMiddleware = require('koa-webpack-dev-middleware')
const hotMiddleware = require('koa-webpack-hot-middleware')
app.use(convert(devMiddleware(compiler, {
publicPath: webpackConfig.output.publicPath,
stats: {
colors: true,
modules: false,
children: false,
chunks: false,
chunkModules: false
}
})))
app.use(convert(hotMiddleware(compiler)))
// server renderer
const serverBundleConfig = require('../config/webpack.bundle')
const serverBundleCompiler = webpack(serverBundleConfig)
const mfs = new MFS()
serverBundleCompiler.outputFileSystem = mfs
serverBundleCompiler.watch({}, (err, stats) => {
if (err) throw err
stats = stats.toJson()
stats.errors.forEach(err => console.error(err))
stats.warnings.forEach(err => console.warn(err))
renderer = createRenderer(mfs)
})
}
else {
// PRODUCTION
// use nginx to serve static files in real
//app.use(convert(serve({rootDir: path.join(process.cwd(), 'build'), rootPath: '/static'})))
app.use(serveStatic(path.join(process.cwd(), 'build')));
renderer = createRenderer(fs)
}
app.use(ctx => {
var start = new Date;
ctx.type = 'text/html; charset=utf-8'
const context = {url: ctx.url}
const title = 'Tripora';
const stream = new PassThrough()
console.log("Checking if server-side cookie exists...");
// See if request sent over an authentication token in their cookies
if(ctx.cookie && ctx.cookie.token) {
console.log("Found cookie token.");
context.token = ctx.cookie.token;
}
stream.write(`<!DOCTYPE html><html style="min-height: 100%;"><head><meta charset="utf-8"/><title>${title}</title>${assets.main.css ? `<link rel="stylesheet" href="${assets.main.css}"/>` : ''}</head><body style="min-height: 100%;">`)
const renderStream = renderer.renderToStream(context)
let firstChunk = true
renderStream.on('data', chunk => {
// we tell the request to ignore files as an initial reuqest
var isPage = ctx.url.split(".").length == 1;
if (firstChunk && context.initialState && isPage) {
stream.write(`<script>window.__INITIAL_STATE__=${serialize(context.initialState, {isJSON: true})}</script>${chunk}`)
firstChunk = false
} else {
stream.write(chunk)
}
})
renderStream.on('end', () => {
stream.write(`<script src="${assets.main.js}"></script></body></html>`)
var ms = new Date - start;
//ctx.set('X-Response-Time', ms + 'ms');
console.log("-- Response time %s %s = %sms", ctx.method, ctx.originalUrl, ms);
ctx.res.end()
})
renderStream.on('error', err => {
console.log("ERROR", err.stack);
throw new Error(`something bad happened when renderToStream: ${err}`)
})
ctx.status = 200
ctx.body = stream
})
const port = process.env.NODE_PORT || 80
app.listen(port, () => {
console.log(`==> Listening at http://localhost:${port}`)
})
Anyone know why the HMR initial request would take so long, and seem to be so random (sometimes 5s, sometimes 30 seconds)? Techneregy.

why I am not able to import lodash in angular2

I am using angular-cli in angular2 rc1 for development.
I have installed lodash node_module through npm and configured it in systemjs using following:
system.config.ts
/***********************************************************************************************
* User Configuration.
**********************************************************************************************/
/** Map relative paths to URLs. */
const map: any = {
};
/** User packages configuration. */
const packages: any = {
};
////////////////////////////////////////////////////////////////////////////////////////////////
/***********************************************************************************************
* Everything underneath this line is managed by the CLI.
**********************************************************************************************/
const barrels: string[] = [
// Angular specific barrels.
'#angular/core',
'#angular/common',
'#angular/compiler',
'#angular/http',
'#angular/router',
'#angular/platform-browser',
'#angular/platform-browser-dynamic',
'ng2-dnd',
'ng2-bootstrap',
'moment',
'lodash',
// Thirdparty barrels.
'rxjs',
// App specific barrels.
'app',
'app/shared',
/** #cli-barrel */
];
const cliSystemConfigPackages: any = {};
barrels.forEach((barrelName: string) => {
if(barrelName=='ng2-dnd'){
cliSystemConfigPackages[barrelName] = { main: 'ng2-dnd' };
}else if (barrelName == 'ng2-bootstrap') {
cliSystemConfigPackages[barrelName] = { main: 'ng2-bootstrap' };
}else if (barrelName == 'lodash') {
cliSystemConfigPackages[barrelName] = { main: 'lodash' };
}else if (barrelName == 'moment') {
cliSystemConfigPackages[barrelName] = { main: 'moment' };
}else{
cliSystemConfigPackages[barrelName] = { main: 'index' };
}
});
/** Type declaration for ambient System. */
declare var System: any;
// Apply the CLI SystemJS configuration.
System.config({
map: {
'#angular': 'vendor/#angular',
'rxjs': 'vendor/rxjs',
'main': 'main.js',
'ng2-dnd': 'vendor/ng2-dnd',
'ng2-bootstrap':'vendor/ng2-bootstrap',
'moment':'vendor/moment',
'lodash':'vendor/lodash'
},
meta: {
lodash: { format: 'amd' }
},
packages: cliSystemConfigPackages
});
// Apply the user's configuration.
System.config({ map, packages });
I would just like to note that other node_modules are working correctly i.e. moment,ng2-bootstrap etc.
angular-cli-build.js
/* global require, module */
var Angular2App = require('angular-cli/lib/broccoli/angular2-app');
module.exports = function(defaults) {
return new Angular2App(defaults, {
vendorNpmFiles: [
'systemjs/dist/system-polyfills.js',
'systemjs/dist/system.src.js',
'zone.js/dist/**/*.+(js|js.map)',
'es6-shim/es6-shim.js',
'reflect-metadata/**/*.+(js|js.map)',
'rxjs/**/*.+(js|js.map)',
'#angular/**/*.+(js|js.map)',
'ng2-dnd/**/*.js',
'ng2-bootstrap/**/*.js',
'moment/*.js',
'lodash/*.js'
]
});
};
after this configuration of lodash node_module, I am importing it from the directory dist\vendors\lodash
in my app.component i am importing it as :
import _ from 'lodash';
But I am getting below error:
Cannot find module 'lodash'
any solutions?
thanks in advance
I can suggest you a workaround until they get better support for 3rd party libs. It worked for me :)
In your angular-cli-build.json , make sure it remains like this way
module.exports = function(defaults) {
return new Angular2App(defaults, {
vendorNpmFiles: [
...
'lodash/**/*.js'
]
});
};
and in your system-config.ts:
/** Map relative paths to URLs. */
const map: any = {
'lodash': 'vendor/lodash/lodash.js'
};
/** User packages configuration. */
const packages: any = {
'lodash': {
format: 'cjs'
}
};
in your src/index.html add this line
<script src="/vendor/lodash/lodash.js" type="text/javascript"></script>
now in your component where you want to use lodash , write this way
declare var _:any;
#Component({
})
export class YourComponent {
ngOnInit() {
console.log(_.chunk(['a', 'b', 'c', 'd'], 2));
}
}
Try using:
import * as _ from 'lodash';

Resources