Open lmartins opened 6 years ago
I am trying to do this. Because I got the message WARNING in entrypoint size limit...
while slate building.
externals
of webpack in 'production' to reduce the size of bundle file. It can be done by the following code.
Refer: webpack externals// ./slate.config.js
const externals = {
jquery: 'jQuery',
};
module.exports = {
slateCssVarLoader: {
cssVarLoaderLiquidPath: ['src/snippets/css-variables.liquid'],
},
slateTools: {
extends: {
dev: {
resolve: {alias},
},
prod: {
resolve: {alias},
externals,
},
},
},
};
<!-- ./src/layout/theme.liquid -->
<head>
...
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
{% include 'script-tags', layout: 'theme' %}
...
</head>
development
(not done yet)
Usually...it just need to add a condition of env
for the jquery <script>
, like this:
<!-- ./src/layout/theme.liquid -->
<head>
...
{% if theme.env == 'production' %}
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
{% endif %}
{% include 'script-tags', layout: 'theme' %}
...
</head>
But I don't know how to get the current env
in liquid. Need help...
In the other hand, is it possible to be done by extending the scripts-tags
?
Same here,
I'm trying to upload the translation file for jQuery validate inside theme.liquid :
<script src="https://localhost:8080/messages_fr.min.js"></script>
And I'm getting Uncaught ReferenceError: jQuery is not defined error inside Chrome console.
I have been digging into this issue as well, and like @lmartins I would have thought adding the webpack.ProvidePlugin into slate.config.js
would do the trick.
Looking at slate-tools' dev.js
and prod.js
files it appears that Slate's core.js plugins are applied first, then the mode's plugins and finally the user config plugins. My guess is that the webpack.ProvidePlugin
would need to be loaded prior to the webpack.HotModuleReplacementPlugin
.
Adding the ProviderPlugin directly to core.js
does work, but that's basically injecting jQuery into everything.
// core.js
...
const plugins = [
new webpack.ContextReplacementPlugin(
/__appsrc__/,
replaceCtxRequest(paths.src),
),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
}),
];
...
Similar to the newer slateCssVarLoader
object in slate.config.js
, it might make sense to provide a way to pass along and object of ProviderPlugins.
It's also entirely possible that I'm missing something obvious since I'm newer to webpack.
Here is a much cleaner solution to set global jQuery
or $
for legacy modules and typical jQuery plugins. Best of all Slate allows for this to be supported with the slate.config.js
file.
The correct approach is outlined on Webpack's docs under Granular Shimming. https://webpack.js.org/guides/shimming/#granular-shimming
The webpack compiler can understand modules written as ES2015 modules, CommonJS or AMD. However, some third party libraries may expect global dependencies (e.g. $ for jQuery). The libraries might also create globals which need to be exported. These "broken modules" are one instance where shimming comes into play.
Here is an example where the imports-loader is used to add a global $ and jQuery variable requiring jquery to the top of the shopify-cartjs
module.
yarn add imports-loader
slate.config.js
to set jQuery and $ for the shopify-cartjs
module for both dev and prod// slate.config.js
/* eslint-disable no-undef */
const path = require('path');
const alias = {
jquery: path.resolve('./node_modules/jquery'),
'lodash-es': path.resolve('./node_modules/lodash-es'),
};
module.exports = {
slateCssVarLoader: {
cssVarLoaderLiquidPath: ['src/snippets/css-variables.liquid'],
},
slateTools: {
extends: {
dev: {
resolve: {alias},
module: {
rules: [
{
test: require.resolve('shopify-cartjs'),
use: 'imports-loader?$=jquery,jQuery=jquery',
},
],
},
},
dev: {
resolve: {alias},
module: {
rules: [
{
test: require.resolve('shopify-cartjs'),
use: 'imports-loader?$=jquery,jQuery=jquery',
},
],
},
},
},
},
};
Give it a try, and it should close out this issue.
@t-kelly Should we start updating https://github.com/Shopify/slate/wiki/Slate-Config with these examples? Or did you have something specific in mind for that page?
@jonathanmoore sorry I've missed the notification on your comment. This does help a lot, thank you! :)
Oddly enough this isn't working for me in a pretty fresh slate build.
Also using it to get CartJS to play nicely with Slate.
Here's my slate.config.js
file:
/* eslint-disable no-undef */
const path = require('path');
const alias = {
jquery: path.resolve('./node_modules/jquery'),
'lodash-es': path.resolve('./node_modules/lodash-es'),
};
module.exports = {
slateCssVarLoader: {
cssVarLoaderLiquidPath: ['src/snippets/css-variables.liquid'],
},
slateTools: {
extends: {
dev: {
resolve: {alias},
module: {
rules: [
{
test: require.resolve('shopify-cartjs'),
use: 'imports-loader?$=jquery,jQuery=jquery',
},
],
},
},
dev: {
resolve: {alias},
module: {
rules: [
{
test: require.resolve('shopify-cartjs'),
use: 'imports-loader?$=jquery,jQuery=jquery',
},
],
},
},
},
},
};
Here's my package.json:
{
"name": "soma-water",
"version": "1.0.0-alpha.1",
"private": true,
"author": "Shopify Inc.",
"description": "An opinionated, Slate compatible, starting point for developing Shopify themes.",
"keywords": [
"shopify",
"theme"
],
"bugs": "https://github.com/Shopify/starter-theme/issues",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/Shopify/starter-theme.git"
},
"devDependencies": {
"@shopify/slate-tools": ">=1.0.0-beta.1",
"babel-preset-shopify": "^16.2.0",
"eslint-plugin-shopify": "^19.0.0",
"stylelint-config-prettier": "^3.0.4",
"stylelint-config-shopify": "^5.0.0"
},
"dependencies": {
"@shopify/theme-a11y": "^1.0.0-alpha.3",
"@shopify/theme-cart": "^1.0.0-alpha.3",
"@shopify/theme-currency": "^1.0.0-alpha.3",
"@shopify/theme-images": "^1.0.0-alpha.3",
"@shopify/theme-rte": "^1.0.0-alpha.3",
"@shopify/theme-sections": "^1.0.0-alpha.4",
"@shopify/theme-variants": "^1.0.0-alpha.5",
"imports-loader": "^0.8.0",
"jquery": "^3.2.1",
"lazysizes": "^4.0.2",
"lodash-es": "^4.17.4",
"normalize.css": "^7.0.0",
"shopify-cartjs": "^0.4.1"
},
"scripts": {
"start": "slate-tools start",
"watch": "slate-tools start --skipFirstDeploy",
"build": "slate-tools build",
"deploy": "slate-tools build && slate-tools deploy",
"zip": "slate-tools build && slate-tools zip",
"lint": "slate-tools lint",
"format": "slate-tools format"
}
}
I'm initializing CartJS
at the bottom of my theme.liquid
layout file.
<!doctype html>
<!--[if IE 9]> <html class="ie9 no-js supports-no-cookies" lang="{{ shop.locale }}"> <![endif]-->
<!--[if (gt IE 9)|!(IE)]><!--> <html class="no-js supports-no-cookies" lang="{{ shop.locale }}"> <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="theme-color" content="{{ settings.color_accent }}">
<link rel="canonical" href="{{ canonical_url }}">
{%- if settings.favicon != blank -%}
<link rel="shortcut icon" href="{{ settings.favicon | img_url: '32x32' }}" type="image/png">
{%- endif -%}
{%- capture seo_title -%}
{{ page_title }}
{%- if current_tags -%}
{%- assign meta_tags = current_tags | join: ', ' -%} – {{ 'general.meta.tags' | t: tags: meta_tags -}}
{%- endif -%}
{%- if current_page != 1 -%}
– {{ 'general.meta.page' | t: page: current_page }}
{%- endif -%}
{%- assign escaped_page_title = page_title | escape -%}
{%- unless escaped_page_title contains shop.name -%}
– {{ shop.name }}
{%- endunless -%}
{%- endcapture -%}
<title>{{ seo_title | strip }}</title>
{%- if page_description -%}
<meta name="description" content="{{ page_description | escape }}">
{%- endif -%}
{% include 'social-meta-tags' %}
{% include 'style-tags' %}
{% include 'css-variables' %}
<script>
document.documentElement.className = document.documentElement.className.replace('no-js', '');
window.theme = {
strings: {
addToCart: {{ 'products.product.add_to_cart' | t | json }},
soldOut: {{ 'products.product.sold_out' | t | json }},
unavailable: {{ 'products.product.unavailable' | t | json }}
},
moneyFormat: {{ shop.money_format | json }}
};
</script>
{% include 'script-tags', layout: 'theme' %}
{{ content_for_header }}
</head>
<body id="{{ page_title | handle }}" class="template-{{ template.name | handle }}">
<a class="in-page-link visually-hidden skip-link" href="#MainContent">{{ 'general.accessibility.skip_to_content' | t }}</a>
{% section 'header' %}
<main role="main" id="MainContent">
{{ content_for_layout }}
</main>
{% section 'footer' %}
{{ 'option_selection.js' | shopify_asset_url | script_tag }}
<script type="text/javascript">
jQuery(function() {
CartJS.init({{ cart | json }});
});
</script>
</body>
</html>
Hate to make this seem like a trouble-shooting type question but after literally copy/pasting and installing imports-loader
I'm at a loss on how to get Shopify to play nice.
@patrickbjohnson I'm at the same point as you, did you figure it out?
Hey guys, has anyone found the solution for this? I'm trying to import owl.carousel and I get similar errors, I tried @jonathanmoore solution with no luck.
This is what I have in my script: assets/scripts/components/collection_build.js
import $ from 'jquery';
import {formatMoney} from '@shopify/theme-currency';
import 'owl.carousel';
And this is my slate.config.js:
/* eslint-disable no-undef */
const path = require('path');
const alias = {
jquery: path.resolve('./node_modules/jquery'),
'lodash-es': path.resolve('./node_modules/lodash-es'),
};
module.exports = {
slateCssVarLoader: {
cssVarLoaderLiquidPath: ['src/snippets/css-variables.liquid'],
},
slateTools: {
extends: {
dev: {
resolve: {alias},
module: {
rules: [
{
test: require.resolve('./node_modules/owl.carousel'),
use: 'imports-loader?$=jquery,jQuery=jquery',
},
],
},
},
prod: {
resolve: {alias},
module: {
rules: [
{
test: require.resolve('./node_modules/owl.carousel'),
use: 'imports-loader?$=jquery,jQuery=jquery',
},
],
},
},
},
},
};
And I get this error:
Uncaught TypeError: Cannot read property 'fn' of undefined
at eval (webpack-internal:///../node_modules/owl.carousel/dist/owl.carousel.js:1718)
at eval (webpack-internal:///../node_modules/owl.carousel/dist/owl.carousel.js:1755)
at Object.../node_modules/owl.carousel/dist/owl.carousel.js (template.collection.js:1289)
at __webpack_require__ (template.collection.js:712)
at fn (template.collection.js:95)
at eval (webpack-internal:///./assets/scripts/components/collection_build.js:9)
at Object../assets/scripts/components/collection_build.js (template.collection.js:1471)
at __webpack_require__ (template.collection.js:712)
at fn (template.collection.js:95)
at eval (webpack-internal:///./assets/scripts/templates/collection.js:7)
For anyone having the same issue as me with adding owl.carousel, I found that @jonathanmoore have found a way to do it, here is how he solved the issue.
Instead of using import:
import $ from 'jquery';
import {formatMoney} from '@shopify/theme-currency';
import 'owl.carousel';
You need to do this:
import $ from 'jquery';
window.jQuery = $;
window.$ = $;
require('owl.carousel');
Check his example here: https://github.com/jonathanmoore/starter-theme/pull/2/files
This is also mentioned on issue #605
Problem
I am trying to use https://github.com/discolabs/cartjs as a CommonJS module, which is a library that depends on
jQuery
to be available on the window object.One way Webpack allows to use this is via the
ProvidePlugin
https://webpack.js.org/plugins/provide-plugin/, so I wonder how can we achieve that using Slate's config file.More Information
I've tried to expose a plugins array to the dev config, but that unfortunately didn't worked:
The only thing that worked was to create a jQuery global variable inside my module, which feels like a wrong approach to it.
Any tips on better solution to this?