Undefined .env variables when webpack goes into production mode - node.js

I'm using the dot-env NPM package in order to pass simple variables to my webpack/express application.
When I run in PRODUCTION mode for webpack, all my variables from .env become undefined.
I'm building up a development and production webpack config files and currently have the following setup.
Any advise on the mistakes I'm making and why my .env variables are being dropped would be greatly appreciated.
package.json (Scripts)
"buildDev": "rm -rf dist && webpack --mode development --config webpack.server.config.js && webpack --mode development --config webpack.dev.config.js",
"buildProd": "rm -rf dist && webpack --mode production --config webpack.server.config.js && webpack --mode production --config webpack.prod.config.js",
webpack.dev
const path = require("path");
const webpack = require("webpack");
const HtmlWebPackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const paths = require("./config/paths");
const isDevelopment = false;
const Dotenv = require('dotenv-webpack');
require('dotenv').config()
module.exports = {
entry: {
main: [
"webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000",
paths.appIndexJs,
],
},
output: {
path: path.join(__dirname, "dist"),
publicPath: "/",
filename: "[name].js",
},
devServer: {
historyApiFallback: true,
},
mode: "production",
target: "web",
devtool: "#source-map",
module: {
rules: [
{
enforce: "pre",
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: "eslint-loader",
options: {
emitWarning: true,
failOnError: false,
failOnWarning: false,
},
},
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
include: path.resolve(paths.appSrc),
loader: "babel-loader",
},
{
// Loads the javacript into html template provided.
// Entry point is set below in HtmlWebPackPlugin in Plugins
test: /\.html$/,
include: path.resolve(paths.appSrc),
use: [
{
loader: "html-loader",
},
],
},
{
test: /\.css$/,
include: path.resolve(paths.appSrc),
use: ["style-loader", "css-loader"],
},
{
test: /\.css$/,
include: /node_modules/,
use: ["style-loader", "css-loader"],
},
{
test: /\.scss$/,
use: ["style-loader", "css-loader", "sass-loader"],
},
{
test: /\.(png|svg|jpg|gif|eot|woff|woff2|ttf)$/,
use: ["file-loader"],
},
],
},
resolve: {
extensions: [".js", ".jsx"],
},
plugins: [
new HtmlWebPackPlugin({
favicon: "./src/assets/img/favicons/favicon.ico",
template: "./src/html/index.html",
filename: "./index.html",
excludeChunks: ["server"],
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
new Dotenv()
],
};
webpack.prod
const path = require("path");
const webpack = require("webpack");
const HtmlWebPackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const paths = require("./config/paths");
const isDevelopment = false;
const Dotenv = require('dotenv-webpack');
require('dotenv').config()
module.exports = {
entry: {
main: [
"webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000",
paths.appIndexJs,
],
},
output: {
path: path.join(__dirname, "dist"),
publicPath: "/",
filename: "[name].js",
},
devServer: {
historyApiFallback: true,
},
mode: "production",
target: "web",
devtool: "#source-map",
module: {
rules: [
{
enforce: "pre",
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: "eslint-loader",
options: {
emitWarning: true,
failOnError: false,
failOnWarning: false,
},
},
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
include: path.resolve(paths.appSrc),
loader: "babel-loader",
},
{
// Loads the javacript into html template provided.
// Entry point is set below in HtmlWebPackPlugin in Plugins
test: /\.html$/,
include: path.resolve(paths.appSrc),
use: [
{
loader: "html-loader",
},
],
},
{
test: /\.css$/,
include: path.resolve(paths.appSrc),
use: ["style-loader", "css-loader"],
},
{
test: /\.css$/,
include: /node_modules/,
use: ["style-loader", "css-loader"],
},
{
test: /\.scss$/,
use: ["style-loader", "css-loader", "sass-loader"],
},
/*{
test: /\.scss$/,
use: [
{ loader: 'css-loader', options: { url: false, sourceMap: true } },
{ loader: 'sass-loader', options: { sourceMap: true }
},
]
},*/
/*{
test: /\.css$/,
include: path.resolve(paths.appSrc),
use: ["style-loader", "css-loader"],
},
{
test: /\.sass$/,
use: [
MiniCssExtractPlugin.loader,
{ loader: 'css-loader', options: { url: false, sourceMap: true } },
{ loader: 'sass-loader', options: { sourceMap: true } },
]
},
{
test: /\.css$/,
include: /node_modules/,
loader: [
isDevelopment ? "style-loader" : MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
modules: true,
sourceMap: isDevelopment,
},
},
],
},
{
test: /\.(scss)$/,
use: [
MiniCssExtractPlugin.loader, { loader: 'css-loader',
options: { url: false, sourceMap:
true } }, { loader: 'sass-loader', options: { sourceMap: true } },
]
},*/
{
test: /\.(png|svg|jpg|gif|eot|woff|woff2|ttf)$/,
//include: path.resolve(paths.appSrc),
use: ["file-loader"],
},
],
},
resolve: {
extensions: [".js", ".jsx"],
},
plugins: [
new webpack.DefinePlugin({
'process.env': { 'NODE_ENV': JSON.stringify('production') }
}),
new HtmlWebPackPlugin({
favicon: "./src/assets/img/favicons/favicon.ico",
template: "./src/html/index.html",
filename: "./index.html",
excludeChunks: ["server"],
}),
new webpack.NoEmitOnErrorsPlugin(),
new Dotenv()
],
};
webpack.server
const path = require("path");
const webpack = require("webpack");
const nodeExternals = require("webpack-node-externals");
const HtmlWebPackPlugin = require("html-webpack-plugin");
module.exports = (env, argv) => {
const SERVER_PATH =
argv.mode === "production" ? "./src/server/server-prod.js" : "./src/server/server-dev.js";
return {
entry: {
server: SERVER_PATH,
},
output: {
path: path.join(__dirname, "dist"),
publicPath: "/",
filename: "[name].js",
},
mode: argv.mode,
target: "node",
node: {
// Need this when working with express, otherwise the build fails
__dirname: false, // if you don't put this is, __dirname
__filename: false, // and __filename return blank or /
},
externals: [nodeExternals()], // Need this to avoid error when working with Express
devServer: {
historyApiFallback: true,
},
module: {
rules: [
{
// Transpiles ES6-8 into ES5
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
},
}
],
},
};
};

If you look at yow webpack.prod in its plugins section you have it like.
new webpack.DefinePlugin({
'process.env': { 'NODE_ENV': JSON.stringify('production') }
So basically you is setting process.env to be equals to What Eva is there
solution
first you need to install two modules
dotenv-expand
dotenv
$ npm i -D dotenv-expand dotenv
Next
create a new file called env.js, I mean the name is up to you. Place the file same place where yow webpacks are
env.js
'use strict';
const fs = require('fs');
const path = require('path');
const {NODE_ENV} = process.env.NODE_ENV;
const dotenvFile = `.env.${NODE_ENV}`;
require('dotenv-expand')(
require('dotenv').config({
path: dotenvFile,
}));
const appDirectory = fs.realpathSync(process.cwd());
process.env.NODE_PATH = (process.env.NODE_PATH || '')
.split(path.delimiter)
.filter(folder => folder && !path.isAbsolute(folder))
.map(folder => path.resolve(appDirectory, folder))
.join(path.delimiter);
// set your own prefix
const PREFIX = /^ENETO_/i;
function getEnvironment() {
const raw = Object.keys(process.env)
.filter(key => PREFIX.test(key))
.reduce(
(env, key) => {
env[key] = process.env[key];
return env;
},
{
NODE_ENV: process.env.NODE_ENV || 'development',
PORT: process.env.PORT||3000,
}
);
const stringified = {
'process.env': Object.keys(raw).reduce((env, key) => {
env[key] = JSON.stringify(raw[key]);
return env;
}, {}),
};
console.log("stringified", stringified);
return { raw, stringified };
}
module.exports = getEnvironment();
NOTE
Make sure to add a prefix so all of them shuld start with a PREFIX
you can set your own prefix
now on each one of yow webpacks add it;
webpack.server.js
/**
webpack server
*/
"use strict";
const path = require("path");
const nodeExternals = require("webpack-node-externals");
const webpack = require("webpack");
/**
* HERE IS IMPORTED ALL THE WAY TO THE BOTTOM YOU'LL SEE IT
*/
const vars = require("./env");
const { NODE_ENV } = process.env;
const entry = [path.join(__dirname, NODE_ENV === "production" ? `../src/prod.ts` : `../src/dev.ts`)];
module.exports = {
target: "node",
name: "server",
externals: [nodeExternals()],
entry: [
require.resolve("#babel/register"),
require.resolve("core-js/proposals"),
require.resolve("core-js"),
require.resolve("#babel/runtime-corejs3/regenerator"),
require.resolve("es6-promise/auto"),
...entry,
],
devtool: false,
mode: process.env.NODE_ENV,
output: {
filename: "[name]-bundle.js",
chunkFilename: "[name].chunk.js",
path: path.resolve(__dirname, "../bundle"),
publicPath: "/",
libraryTarget: "commonjs2",
},
resolve: {
extensions: [".ts", ".tsx", ".js"],
},
module: {
rules: [
{
test: /\.tsx?$/,
exclude: /node_modules/,
use: [
{
loader: "babel-loader",
},
],
},
{
test: /\.(js|mjs)$/,
exclude: /#babel(?:\/|\\{1,2})runtime/,
loader: require.resolve("babel-loader"),
options: {
babelrc: false,
configFile: false,
compact: false,
presets: [[require.resolve("#babel/preset-env")]],
cacheDirectory: true,
cacheCompression: false,
sourceMaps: false,
inputSourceMap: false,
},
},
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: "file-loader",
},
],
},
],
},
plugins: [new webpack.DefinePlugin(vars.stringified)],
};
Do the same with yow client and thats it :3

do not need third part deps.
just use env like this:
--node-env=
// in package.json
"build": "webpack --node-env=production --config build/webpack.config.js"
or
module.exports = (env, argv) => {
const isDevelopment = argv.mode !== 'production';
return {
// Config...
}
}
see:
--node-env
argv

Related

webpack 4 extraer multiples css

I am using webpack 4. I need to be able to extract the scss to css in separate files.
index.js
import "./styles/styles.scss";
import "./styles/stylesapp.scss";
import "./styles/..."; / more files scss
convert to styles/styles.css and styles/stylesapp.css,
The problems that happened to me.
ExtractTextPlugin = not soport webpack4
MiniCssExtractPlugin = extract the file but I want to send more than one css
const webpack = require("webpack");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const TerserPlugin = require("terser-webpack-plugin");
const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const path = require("path");
const config = {
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "bundle.js"
},
module: {
rules: [
{
test: /\.scss$/,
use: [
"style-loader",
{
loader: MiniCssExtractPlugin.loader
},
"css-loader",
"sass-loader"
]
},
{
test: /\.css$/,
use: [
"style-loader",
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
importLoaders: 1,
modules: true
}
}
],
include: /\.module\.css$/
},
{
test: /\.woff(2)?(\?v=\d+\.\d+\.\d+)?$/,
loader:
"url-loader?limit=10000&mimetype=application/font-woff&name=fonts/[name].[ext]&publicPath=../"
},
{
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
loader:
"url-loader?limit=10000&mimetype=application/octet-stream&name=fonts/[name].[ext]&publicPath=../"
},
{
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
loader: "file-loader?name=fonts/[name].[ext]&publicPath=../"
},
{
test: /\.(gif|jpg|png|ico)(\?v=\d+\.\d+\.\d+)?$/,
loader: "file-loader?name=images/[contenthash].[ext]&publicPath=../"
},
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
loader:
"url-loader?limit=10000&mimetype=image/svg+xml&name=images/[name].[ext]&publicPath=../"
}
]
},
resolve: {
alias: {
styles: path.resolve(__dirname, "src/styles"),
assets: path.resolve(__dirname, "src/assets"),
fonts: path.resolve(__dirname, "src/fonts")
}
},
optimization: {
minimizer: []
},
plugins: [
new TerserPlugin(),
new OptimizeCssAssetsPlugin(),
new CleanWebpackPlugin(),
new MiniCssExtractPlugin({
filename: "style/[name].css"
})
]
};
// eslint-disable-next-line no-undef
module.exports = config;
sorry for my English. thanks.

Much older version of my Website shows when rebuilding Production Bundle with Webpack

I've noticed that when I rebuild my production bundle of my node.js app using webpack, the site in the browser reverts to a way older version (300+ git commits later). I use pm2 to run my website on my VPS.
How to keep the oldest version live until the new production build is done?
This is my webpack setup:
const { resolve } = require('path');
const webpack = require('webpack');
const CompressionPlugin = require('compression-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const cssOutputLocation = process.env.NODE_ENV === 'production' ?
'public/stylesheets/style-prod.css' :
'stylesheets/style.css';
const jsProdOutput = {
filename: 'public/javascripts/build-prod.js',
path: resolve(__dirname),
publicPath: '/',
};
const jsDevOutput = {
filename: 'javascripts/build.js',
path: '/',
publicPath: '/',
};
const jsOutputLocation = process.env.NODE_ENV === 'production' ? jsProdOutput : jsDevOutput;
module.exports = {
context: resolve(__dirname, 'src'),
entry: [
'./index.jsx',
],
output: jsOutputLocation,
resolve: {
extensions: ['.js', '.jsx'],
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components|public\/)/,
loader: 'babel-loader',
query: {
presets: ['es2015', 'es2017'],
},
},
{
test: /\.js?$/,
exclude: /(node_modules|bower_components|public\/)/,
loader: 'babel-loader',
query: {
presets: ['es2015', 'es2017'],
},
},
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: 'css-loader',
}),
},
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
use: [
{
loader: 'css-loader',
},
{
loader: 'sass-loader',
},
],
fallback: 'style-loader',
}),
},
],
},
plugins: [
new webpack.NamedModulesPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
new ExtractTextPlugin(cssOutputLocation),
new BundleAnalyzerPlugin(),
new webpack.ContextReplacementPlugin(/^\.\/locale$/, (context) => {
if (!/\/moment\//.test(context.context)) { return; }
// context needs to be modified in place
Object.assign(context, {
// include only CJK
regExp: /^\.\/(nl|en-gb)/,
// point to the locale data folder relative to moment's src/lib/locale
request: '../../locale',
});
}),
],
};
if (process.env.NODE_ENV === 'production') {
module.exports.plugins.push(new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
screw_ie8: true,
conditionals: true,
unused: true,
comparisons: true,
sequences: true,
dead_code: true,
evaluate: true,
if_return: true,
join_vars: true,
},
output: {
comments: false,
},
}));
module.exports.plugins.push(new webpack.HashedModuleIdsPlugin());
module.exports.plugins.push(new webpack.optimize.ModuleConcatenationPlugin());
module.exports.plugins.push(
new webpack.DefinePlugin(
{ 'process.env.NODE_ENV': JSON.stringify('production') },
),
);
module.exports.plugins.push(
new CompressionPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: /\.js$|\.css$|\.html$|\.eot?.+$|\.ttf?.+$|\.woff?.+$|\.svg?.+$/,
threshold: 10240,
minRatio: 0.8,
}),
);
}
if (process.env.NODE_ENV !== 'production') {
module.exports.entry.unshift(
'react-hot-loader/patch',
'react-hot-loader/babel',
'webpack-hot-middleware/client',
);
module.exports.plugins.unshift(new webpack.HotModuleReplacementPlugin());
}
You can use the hash placeholder in the filename prop of your output config.
const jsProdOutput = {
filename: 'public/javascripts/build-prod-[hash].js',
path: resolve(__dirname),
publicPath: '/',
};
With this your generated files will be unique on every build and will not be overridden.

asset_url_for() returns None in flask cookie cutter (flask-webpack)

Im new to webpack. Im using flask-cookie-cutter which in turn uses Flask-Webpack
Im having issues in that App wont find my images in development.
Images are in assets/img folder
Ive tried using {{ asset_url_for('img/img_name.png') }} and various variations of it - and it just returns none.
Ive tried the usual flask way of {{ url_for('static', filename='img/img_name.png') }}
But I cant seem to access them.
const path = require('path');
const webpack = require('webpack');
/*
* Webpack Plugins
*/
const ManifestRevisionPlugin = require('manifest-revision-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
// take debug mode from the environment
const debug = (process.env.NODE_ENV !== 'production');
// Development asset host (webpack dev server)
const publicHost = debug ? 'http://0.0.0.0:2992' : '';
const rootAssetPath = path.join(__dirname, 'assets');
module.exports = {
// configuration
context: __dirname,
entry: {
main_js: './assets/js/main',
main_css: [
path.join(__dirname, 'node_modules', 'materialize-css', 'dist', 'css', 'materialize.css'),
path.join(__dirname, 'assets', 'css', 'style.css'),
],
},
output: {
path: path.join(__dirname, 'dsi_website', 'static', 'build'),
publicPath: `${publicHost}/static/build/`,
filename: '[name].[hash].js',
chunkFilename: '[id].[hash].js',
},
resolve: {
extensions: ['.js', '.jsx', '.css'],
},
devtool: 'source-map',
devServer: {
headers: { 'Access-Control-Allow-Origin': '*' },
},
module: {
rules: [
{
test: /\.less$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
hmr: debug,
},
},
'css-loader!less-loader',
],
},
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
hmr: debug,
},
},
'css-loader',
],
},
{
test: /\.html$/,
loader: 'raw-loader'
},
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/font-woff'
}
},
{
test: /\.(ttf|eot|svg|png|jpe?g|gif|ico)(\?.*)?$/i,
loader: `file-loader?context=${rootAssetPath}&name=[path][name].[hash].[ext]`
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: ['env'],
cacheDirectory: true
}
},
],
},
plugins: [
new MiniCssExtractPlugin({ filename: '[name].[hash].css', }),
new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' }),
new ManifestRevisionPlugin(path.join(__dirname, 'dsi_website', 'webpack', 'manifest.json'), {
rootAssetPath,
ignorePaths: ['/js', '/css'],
}),
].concat(debug ? [] : [
// production webpack plugins go here
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production'),
}
}),
]),
};
I was the same problem with flask-cookie-cutter and solve it by update/upgrade npm and add extensionsRegex: /\.(jpe?g|png|gif|svg)$/i at down file: webpack.config.js like this:
ManifestRevisionPlugin(path.join(__dirname, '<your app>', 'webpack', 'manifest.json'), {
rootAssetPath,
ignorePaths: ['/js', '/css'],
extensionsRegex: /\.(jpe?g|png|gif|svg)$/i
}),
source solution. Proper call to show image in temaplate:
{{ asset_url_for('img/img_name.png') }}
after that i check startup screen and i see that all my images load properly
[WEBPACK] _/assets/img/image_name.20aed528d50316c91ffedb5ba47b8c74.jpg 18.9 KiB [emitted]

configure webpack to load .vue files in node_modules

I would like to require .vue files from within my node_modules folder but it seems that webpack and | or the .vue loader doesn't transform this files.
This is my configuration right now:
const path = require('path')
const webpack = require('webpack')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
const { VueLoaderPlugin } = require('vue-loader')
const isProd = process.env.NODE_ENV === 'production'
module.exports = {
devtool: isProd
? false
: '#cheap-module-source-map',
output: {
path: path.resolve(__dirname, '../dist'),
publicPath: '/dist/',
filename: '[name].[chunkhash].js'
},
resolve: {
alias: {
'public': path.resolve(__dirname, '../public')
}
},
module: {
noParse: /es6-promise\.js$/, // avoid webpack shimming process
rules: [
{
test: /\.pug$/,
loader: 'pug-plain-loader'
},
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
compilerOptions: {
preserveWhitespace: false
}
}
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'url-loader',
options: {
limit: 10000,
name: '[name].[ext]?[hash]'
}
},
{
test: /\.styl(us)?$/,
use: isProd
? ExtractTextPlugin.extract({
use: [
{
loader: 'css-loader',
options: { minimize: true }
},
'stylus-loader'
],
fallback: 'vue-style-loader'
})
: ['vue-style-loader', 'css-loader', 'stylus-loader']
},
]
},
performance: {
maxEntrypointSize: 300000,
hints: isProd ? 'warning' : false
},
plugins: isProd
? [
new VueLoaderPlugin(),
new webpack.optimize.UglifyJsPlugin({
compress: { warnings: false, drop_console:true }
}),
new webpack.optimize.ModuleConcatenationPlugin(),
new ExtractTextPlugin({
filename: 'common.[chunkhash].css'
})
]
: [
new VueLoaderPlugin(),
new FriendlyErrorsPlugin()
]
}
I tried to set
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules\/(?!(my_components_folder)\/).*/
}
but without success.
I'm always getting the error:
(function (exports, require, module, __filename, __dirname) { <template lang="pug">
^
SyntaxError: Unexpected token <
How can I configure webpack to also transform files from within the node_modules folder?
I'm using webpack#3.8.1

Webpack 2 - Problems parsing node_module

I'm unit testing with mocha-webpack v1.0.1, node v6.10. However, I'm getting an error from one of our node modules, where webpack couldn't parse a #. This is an internal library that we use that runs fine in another development environment. So, I'm confused why this is happening since you would think that a library in your node_module would be sort of self-sustaining and would know how to parse itself (and is validated as working in another environment).
Error in ./~/abc-components/src/abc-theme/index.scss
Module parse failed: /path/to/app/node_modules/abc-components/src/abc-theme/index.scss Unexpected character '#' (1:0)
You may need an appropriate loader to handle this file type.
| #charset "UTF-8";
| #import "abc-variables";
| #import "alert";
I believe # is an alias we use for resolving the module path in that library. I've modeled my setup after this tutorial.
From package.json:
"unit": "BABEL_ENV=test mocha-webpack --webpack-config build/webpack.test.conf.js --require test/unit/.setup src/**/*.spec.js --recursive --watch"
From build/webpack.test.conf.js config, including some comments of things I've tried:
var path = require('path')
var webpack = require('webpack')
var utils = require('./utils')
var config = require('../config')
// var nodeExternals = require('webpack-node-externals');
function resolve(dir) {
return path.join(__dirname, '..', dir)
}
module.exports = {
entry: {
app: './src/main.js'
},
resolve: {
modules: [path.resolve('./src'), "node_modules"],
extensions: ['.js', '.vue', '.json', '.ts'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'#': resolve('src')
}
},
// externals: [nodeExternals()],
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
// plugins: [
// new webpack.optimize.CommonsChunkPlugin({
// name: "vendor",
// filename: "vendor.js",
// minChunks: function (module) {
// // This prevents stylesheet resources with the .css or .scss extension
// // from being moved from their original chunk to the vendor chunk
// if(module.resource && (/^.*\.(css|scss)$/).test(module.resource)) {
// return false;
// }
// return module.context && module.context.indexOf("node_modules") !== -1;
// }
// }),
// new webpack.DefinePlugin({
// 'process.env': require('../config/test.env')
// })
// ],
module: {
loaders: [
{
test: /\.(js|vue)$/,
// loader: 'eslint-loader',
// enforce: 'pre',
include: [resolve('src'), resolve('test'), resolve('node_modules')],
/* options: {
formatter: require('eslint-friendly-formatter')
} */
},
{
test: /\.pug$/,
loader: 'pug-loader'
},
{
test: /\.vue$/,
loader: 'vue-loader'
// options: vueLoaderConfig
},
{
test: /\.ts$/,
loader: "awesome-typescript-loader",
include: [resolve('src'), resolve('test')]
},
{
test: /\.js$/,
loader: 'babel-loader',
query: {
presets: ['es2015']
},
include: [resolve('src'), resolve('test')]
// exclude: /node_modules/
},
{
test: /\.(mp3|wav)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('audio/[name].[hash:7].[ext]')
}
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
},
resolveLoader: {
alias: {
// necessary to to make lang="scss" work in test when using vue-loader's ?inject option
// see discussion at https://github.com/vuejs/vue-loader/issues/724
'scss-loader': 'sass-loader'
}
}
}
Include following config in loader.
module: {
loaders: [
{
test: /\.(scss|sass)$/i,
include: [
path.resolve(__dirname, 'node_modules'),
path.resolve(__dirname, 'path/to/imported/file/dir'), <== This solved the issue
],
loaders: ["css", "sass"]
},
]
},

Resources